[Openmp-commits] [openmp] fdc9dfc - [OpenMP][Tool] Add Archer option to disable data race analysis for sequential part

Joachim Protze via Openmp-commits openmp-commits at lists.llvm.org
Mon Nov 16 01:49:21 PST 2020


Author: Joachim Protze
Date: 2020-11-16T10:45:21+01:00
New Revision: fdc9dfc8e47750fa27b7e7bde2f62c9af68b99e5

URL: https://github.com/llvm/llvm-project/commit/fdc9dfc8e47750fa27b7e7bde2f62c9af68b99e5
DIFF: https://github.com/llvm/llvm-project/commit/fdc9dfc8e47750fa27b7e7bde2f62c9af68b99e5.diff

LOG: [OpenMP][Tool] Add Archer option to disable data race analysis for sequential part

This introduces the new `ARCHER_OPTIONS` flag `ignore_serial=0|1` to disable
analysis and logging of memory accesses in the sequential part of the OpenMP
application.

In the sequential part of an OpenMP program no data race is possible, unless
there is non-OpenMP concurrency (such as pthreads, MPI, ...). For the latter
reason, this is not active by default.

Besides reducing the runtime overhead for the sequential part of the program,
this reduces the memory overhead for sequential initialization. In combination
with `flush_shadow=1` this can allow analysis of applications, which run close
to the limit of available memory, but only access smaller parts of shared
memory during each OpenMP parallel region.

A problem for this approach is that Archer only gets active, when the OpenMP
runtime gets initialized, which might be after serial initialization of the
application. In such case, it helps to call for example `omp_get_max_threads()`
at the beginning of main.

Differential Revision: https://reviews.llvm.org/D90473

Added: 
    

Modified: 
    openmp/tools/archer/README.md
    openmp/tools/archer/ompt-tsan.cpp
    openmp/tools/archer/tests/lit.cfg
    openmp/tools/archer/tests/races/critical-unrelated.c
    openmp/tools/archer/tests/races/lock-nested-unrelated.c
    openmp/tools/archer/tests/races/lock-unrelated.c
    openmp/tools/archer/tests/races/parallel-simple.c
    openmp/tools/archer/tests/races/task-dependency.c
    openmp/tools/archer/tests/races/task-taskgroup-unrelated.c
    openmp/tools/archer/tests/races/task-taskwait-nested.c
    openmp/tools/archer/tests/races/task-two.c

Removed: 
    


################################################################################
diff  --git a/openmp/tools/archer/README.md b/openmp/tools/archer/README.md
index e3c09722a151..2852fe061d20 100644
--- a/openmp/tools/archer/README.md
+++ b/openmp/tools/archer/README.md
@@ -104,7 +104,11 @@ 
diff erent flags are separated by spaces, e.g.:
 <tr>
 <td class="org-left">flush_shadow</td>
 <td class="org-right">0</td>
-<td class="org-left">Flush shadow memory at the end of an outer OpenMP parallel region. Our experiments show that this can reduce memory overhead by ~30% and runtime overhead by ~10%. This flag is useful for large OpenMP applications that typically require large amounts of memory, causing out-of-memory exceptions when checked by Archer.</td>
+<td class="org-left">Flush shadow memory at the end of an outer OpenMP
+parallel region. Our experiments show that this can reduce memory overhead
+by ~30% and runtime overhead by ~10%. This flag is useful for large OpenMP
+applications that typically require large amounts of memory, causing
+out-of-memory exceptions when checked by Archer.</td>
 </tr>
 </tbody>
 
@@ -116,6 +120,17 @@ 
diff erent flags are separated by spaces, e.g.:
 </tr>
 </tbody>
 
+<tbody>
+<tr>
+<td class="org-left">ignore_serial</td>
+<td class="org-right">0</td>
+<td class="org-left">Turn off tracking and analysis of memory accesses in
+the sequential part of an OpenMP program. (Only effective when OpenMP
+runtime is initialized. In doubt, insert omp_get_max_threads() as first
+statement in main!)</td>
+</tr>
+</tbody>
+
 <tbody>
 <tr>
 <td class="org-left">verbose</td>

diff  --git a/openmp/tools/archer/ompt-tsan.cpp b/openmp/tools/archer/ompt-tsan.cpp
index f8ee7ce78962..3ab0eadbbef0 100644
--- a/openmp/tools/archer/ompt-tsan.cpp
+++ b/openmp/tools/archer/ompt-tsan.cpp
@@ -56,18 +56,14 @@ static int hasReductionCallback;
 class ArcherFlags {
 public:
 #if (LLVM_VERSION) >= 40
-  int flush_shadow;
+  int flush_shadow{0};
 #endif
-  int print_max_rss;
-  int verbose;
-  int enabled;
+  int print_max_rss{0};
+  int verbose{0};
+  int enabled{1};
+  int ignore_serial{0};
 
-  ArcherFlags(const char *env)
-      :
-#if (LLVM_VERSION) >= 40
-        flush_shadow(0),
-#endif
-        print_max_rss(0), verbose(0), enabled(1) {
+  ArcherFlags(const char *env) {
     if (env) {
       std::vector<std::string> tokens;
       std::string token;
@@ -88,6 +84,8 @@ class ArcherFlags {
           continue;
         if (sscanf(it->c_str(), "enable=%d", &enabled))
           continue;
+        if (sscanf(it->c_str(), "ignore_serial=%d", &ignore_serial))
+          continue;
         std::cerr << "Illegal values for ARCHER_OPTIONS variable: " << token
                   << std::endl;
       }
@@ -410,7 +408,7 @@ struct TaskData {
   bool InBarrier;
 
   /// Whether this task is an included task.
-  bool Included;
+  int TaskType{0};
 
   /// Index of which barrier to use next.
   char BarrierIndex;
@@ -443,8 +441,8 @@ struct TaskData {
   int execution;
   int freed;
 
-  TaskData(TaskData *Parent)
-      : InBarrier(false), Included(false), BarrierIndex(0), RefCount(1),
+  TaskData(TaskData *Parent, int taskType)
+      : InBarrier(false), TaskType(taskType), BarrierIndex(0), RefCount(1),
         Parent(Parent), ImplicitTask(nullptr), Team(Parent->Team),
         TaskGroup(nullptr), DependencyCount(0), execution(0), freed(0) {
     if (Parent != nullptr) {
@@ -455,8 +453,8 @@ struct TaskData {
     }
   }
 
-  TaskData(ParallelData *Team = nullptr)
-      : InBarrier(false), Included(false), BarrierIndex(0), RefCount(1),
+  TaskData(ParallelData *Team, int taskType)
+      : InBarrier(false), TaskType(taskType), BarrierIndex(0), RefCount(1),
         Parent(nullptr), ImplicitTask(this), Team(Team), TaskGroup(nullptr),
         DependencyCount(0), execution(1), freed(0) {}
 
@@ -465,6 +463,17 @@ struct TaskData {
     TsanDeleteClock(&Taskwait);
   }
 
+  bool isIncluded() { return TaskType & ompt_task_undeferred; }
+  bool isUntied() { return TaskType & ompt_task_untied; }
+  bool isFinal() { return TaskType & ompt_task_final; }
+  bool isMergable() { return TaskType & ompt_task_mergeable; }
+  bool isMerged() { return TaskType & ompt_task_merged; }
+
+  bool isExplicit() { return TaskType & ompt_task_explicit; }
+  bool isImplicit() { return TaskType & ompt_task_implicit; }
+  bool isInitial() { return TaskType & ompt_task_initial; }
+  bool isTarget() { return TaskType & ompt_task_target; }
+
   void *GetTaskPtr() { return &Task; }
 
   void *GetTaskwaitPtr() { return &Taskwait; }
@@ -517,11 +526,15 @@ static void ompt_tsan_parallel_begin(ompt_data_t *parent_task_data,
   parallel_data->ptr = Data;
 
   TsanHappensBefore(Data->GetParallelPtr());
+  if (archer_flags->ignore_serial && ToTaskData(parent_task_data)->isInitial())
+    TsanIgnoreWritesEnd();
 }
 
 static void ompt_tsan_parallel_end(ompt_data_t *parallel_data,
                                    ompt_data_t *task_data, int flag,
                                    const void *codeptr_ra) {
+  if (archer_flags->ignore_serial && ToTaskData(task_data)->isInitial())
+    TsanIgnoreWritesBegin();
   ParallelData *Data = ToParallelData(parallel_data);
   TsanHappensAfter(Data->GetBarrierPtr(0));
   TsanHappensAfter(Data->GetBarrierPtr(1));
@@ -546,7 +559,7 @@ static void ompt_tsan_implicit_task(ompt_scope_endpoint_t endpoint,
     if (type & ompt_task_initial) {
       parallel_data->ptr = new ParallelData(nullptr);
     }
-    task_data->ptr = new TaskData(ToParallelData(parallel_data));
+    task_data->ptr = new TaskData(ToParallelData(parallel_data), type);
     TsanHappensAfter(ToParallelData(parallel_data)->GetParallelPtr());
     TsanFuncEntry(ToParallelData(parallel_data)->codePtr);
     break;
@@ -727,14 +740,13 @@ static void ompt_tsan_task_create(
     ParallelData *PData = new ParallelData(nullptr);
     parallel_data->ptr = PData;
 
-    Data = new TaskData(PData);
+    Data = new TaskData(PData, type);
     new_task_data->ptr = Data;
   } else if (type & ompt_task_undeferred) {
-    Data = new TaskData(ToTaskData(parent_task_data));
+    Data = new TaskData(ToTaskData(parent_task_data), type);
     new_task_data->ptr = Data;
-    Data->Included = true;
   } else if (type & ompt_task_explicit || type & ompt_task_target) {
-    Data = new TaskData(ToTaskData(parent_task_data));
+    Data = new TaskData(ToTaskData(parent_task_data), type);
     new_task_data->ptr = Data;
 
     // Use the newly created address. We cannot use a single address from the
@@ -801,7 +813,7 @@ static void ompt_tsan_task_schedule(ompt_data_t *first_task_data,
       prior_task_status == ompt_task_late_fulfill) {
     // Included tasks are executed sequentially, no need to track
     // synchronization
-    if (!FromTask->Included) {
+    if (!FromTask->isIncluded()) {
       // Task will finish before a barrier in the surrounding parallel region
       // ...
       ParallelData *PData = FromTask->Team;
@@ -976,10 +988,14 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num,
             "Warning: please export "
             "TSAN_OPTIONS='ignore_noninstrumented_modules=1' "
             "to avoid false positive reports from the OpenMP runtime!\n");
+  if (archer_flags->ignore_serial)
+    TsanIgnoreWritesBegin();
   return 1; // success
 }
 
 static void ompt_tsan_finalize(ompt_data_t *tool_data) {
+  if (archer_flags->ignore_serial)
+    TsanIgnoreWritesEnd();
   if (archer_flags->print_max_rss) {
     struct rusage end;
     getrusage(RUSAGE_SELF, &end);

diff  --git a/openmp/tools/archer/tests/lit.cfg b/openmp/tools/archer/tests/lit.cfg
index ba810d97c3c4..3a67cac0b219 100644
--- a/openmp/tools/archer/tests/lit.cfg
+++ b/openmp/tools/archer/tests/lit.cfg
@@ -91,6 +91,8 @@ if 'INTEL_LICENSE_FILE' in os.environ:
     config.environment['INTEL_LICENSE_FILE'] = os.environ['INTEL_LICENSE_FILE']
 
 # Race Tests
+config.substitutions.append(("%libarcher-compile-and-run-race-noserial", \
+    "%libarcher-compile && env ARCHER_OPTIONS=ignore_serial=1 %libarcher-run-race"))
 config.substitutions.append(("%libarcher-compile-and-run-race", \
     "%libarcher-compile && %libarcher-run-race"))
 config.substitutions.append(("%libarcher-compile-and-run-nosuppression", \

diff  --git a/openmp/tools/archer/tests/races/critical-unrelated.c b/openmp/tools/archer/tests/races/critical-unrelated.c
index 58678a4831b3..af5a6d22ae2a 100644
--- a/openmp/tools/archer/tests/races/critical-unrelated.c
+++ b/openmp/tools/archer/tests/races/critical-unrelated.c
@@ -1,7 +1,6 @@
 /*
  * critical-unrelated.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include <omp.h>
 #include <stdio.h>

diff  --git a/openmp/tools/archer/tests/races/lock-nested-unrelated.c b/openmp/tools/archer/tests/races/lock-nested-unrelated.c
index cf6910dadc39..37b96296c122 100644
--- a/openmp/tools/archer/tests/races/lock-nested-unrelated.c
+++ b/openmp/tools/archer/tests/races/lock-nested-unrelated.c
@@ -1,7 +1,6 @@
 /*
  * lock-nested-unrelated.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include <omp.h>
 #include <stdio.h>

diff  --git a/openmp/tools/archer/tests/races/lock-unrelated.c b/openmp/tools/archer/tests/races/lock-unrelated.c
index d1ac27af21f1..8086ffdb1678 100644
--- a/openmp/tools/archer/tests/races/lock-unrelated.c
+++ b/openmp/tools/archer/tests/races/lock-unrelated.c
@@ -1,7 +1,6 @@
 /*
  * lock-unrelated.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include <omp.h>
 #include <stdio.h>

diff  --git a/openmp/tools/archer/tests/races/parallel-simple.c b/openmp/tools/archer/tests/races/parallel-simple.c
index 2dc87acfd16c..009045ebb46f 100644
--- a/openmp/tools/archer/tests/races/parallel-simple.c
+++ b/openmp/tools/archer/tests/races/parallel-simple.c
@@ -1,7 +1,6 @@
 /*
  * parallel-simple.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include <omp.h>
 #include <stdio.h>

diff  --git a/openmp/tools/archer/tests/races/task-dependency.c b/openmp/tools/archer/tests/races/task-dependency.c
index 0cbd3cf8ef36..d5e2188c205b 100644
--- a/openmp/tools/archer/tests/races/task-dependency.c
+++ b/openmp/tools/archer/tests/races/task-dependency.c
@@ -1,7 +1,6 @@
 /*
  * task-dependency.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include "ompt/ompt-signal.h"
 #include <omp.h>

diff  --git a/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c b/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c
index 244fdd30ac14..7bc03249e363 100644
--- a/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c
+++ b/openmp/tools/archer/tests/races/task-taskgroup-unrelated.c
@@ -1,7 +1,6 @@
 /*
  * task-taskgroup-unrelated.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include "ompt/ompt-signal.h"
 #include <omp.h>

diff  --git a/openmp/tools/archer/tests/races/task-taskwait-nested.c b/openmp/tools/archer/tests/races/task-taskwait-nested.c
index 193ad417a623..29aac18ba8f6 100644
--- a/openmp/tools/archer/tests/races/task-taskwait-nested.c
+++ b/openmp/tools/archer/tests/races/task-taskwait-nested.c
@@ -1,7 +1,6 @@
 /*
  * task-taskwait-nested.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include "ompt/ompt-signal.h"
 #include <omp.h>

diff  --git a/openmp/tools/archer/tests/races/task-two.c b/openmp/tools/archer/tests/races/task-two.c
index 1af937e0341a..281269fc49d4 100644
--- a/openmp/tools/archer/tests/races/task-two.c
+++ b/openmp/tools/archer/tests/races/task-two.c
@@ -1,7 +1,6 @@
 /*
  * task-two.c -- Archer testcase
  */
-
 //===----------------------------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -12,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 // RUN: %libarcher-compile-and-run-race | FileCheck %s
+// RUN: %libarcher-compile-and-run-race-noserial | FileCheck %s
 // REQUIRES: tsan
 #include <omp.h>
 #include <stdio.h>


        


More information about the Openmp-commits mailing list