[Openmp-commits] [openmp] 27c799e - [OpenMP] Ensure broken assumptions print once, not thousands of times.

Joseph Huber via Openmp-commits openmp-commits at lists.llvm.org
Thu Jan 27 15:44:05 PST 2022


Author: Joseph Huber
Date: 2022-01-27T18:43:45-05:00
New Revision: 27c799ecc9e9e3bfb8232c93fd500f45ca0cb345

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

LOG: [OpenMP] Ensure broken assumptions print once, not thousands of times.

If we have a broken assumption we want to print a message to the user.
If the assumption is broken by many threads in many teams this can
become a problem. To avoid it we use a hash that tracks if a broken
assumption has (likely) been printed and avoid printing it again. This
is not fool proof and has some caveats that might cause problems in
the future (see comment) but it should improve the situation
considerably for now.

Reviewed By: JonChesterfield

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

Added: 
    

Modified: 
    openmp/libomptarget/DeviceRTL/include/Debug.h
    openmp/libomptarget/DeviceRTL/include/Synchronization.h
    openmp/libomptarget/DeviceRTL/include/Utils.h
    openmp/libomptarget/DeviceRTL/src/Synchronization.cpp

Removed: 
    


################################################################################
diff  --git a/openmp/libomptarget/DeviceRTL/include/Debug.h b/openmp/libomptarget/DeviceRTL/include/Debug.h
index 18c43f30ab624..7c3979fda780b 100644
--- a/openmp/libomptarget/DeviceRTL/include/Debug.h
+++ b/openmp/libomptarget/DeviceRTL/include/Debug.h
@@ -13,6 +13,7 @@
 #define OMPTARGET_DEVICERTL_DEBUG_H
 
 #include "Configuration.h"
+#include "Utils.h"
 
 /// Assertion
 ///
@@ -25,9 +26,10 @@ void __assert_fail(const char *assertion, const char *file, unsigned line,
 
 #define ASSERT(expr)                                                           \
   {                                                                            \
-    if (config::isDebugMode(config::DebugKind::Assertion) && !(expr))          \
+    if (config::isDebugMode(config::DebugKind::Assertion) && !(expr) &&        \
+        utils::SingletonFlag::testAndSet())                                    \
       __assert_fail(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__);           \
-    else                                                                       \
+    else if (!config::isDebugMode(config::DebugKind::Assertion))               \
       __assert_assume(expr);                                                   \
   }
 

diff  --git a/openmp/libomptarget/DeviceRTL/include/Synchronization.h b/openmp/libomptarget/DeviceRTL/include/Synchronization.h
index e33f37a659af2..70d26565f9ccc 100644
--- a/openmp/libomptarget/DeviceRTL/include/Synchronization.h
+++ b/openmp/libomptarget/DeviceRTL/include/Synchronization.h
@@ -74,6 +74,10 @@ uint32_t add(uint32_t *Addr, uint32_t V, int Ordering);
 /// Atomically add \p V to \p *Addr with \p Ordering semantics.
 uint64_t add(uint64_t *Addr, uint64_t V, int Ordering);
 
+/// Atomically write \p V to \p *Addr with \p Ordering semantics and return the
+/// old value of \p *Addr.
+uint32_t exchange(uint32_t *Addr, uint32_t V, int Ordering);
+
 } // namespace atomic
 
 } // namespace _OMP

diff  --git a/openmp/libomptarget/DeviceRTL/include/Utils.h b/openmp/libomptarget/DeviceRTL/include/Utils.h
index dc4b1cd71a593..9a0711ffa52af 100644
--- a/openmp/libomptarget/DeviceRTL/include/Utils.h
+++ b/openmp/libomptarget/DeviceRTL/include/Utils.h
@@ -12,6 +12,7 @@
 #ifndef OMPTARGET_DEVICERTL_UTILS_H
 #define OMPTARGET_DEVICERTL_UTILS_H
 
+#include "Synchronization.h"
 #include "Types.h"
 
 namespace _OMP {
@@ -72,6 +73,26 @@ template <typename Ty1, typename Ty2> inline Ty1 align_down(Ty1 V, Ty2 Align) {
   return V - V % Align;
 }
 
+namespace {
+/// Helper class to perform an action only once.
+///
+/// Using this is probably costly even if it is not executed. It should be
+/// guarded such that release mode execution will not be impacted.
+template <uint32_t ID> struct SingletonFlagImpl {
+
+  /// Each SingletonFlag instantiation with the same ID has an internal flag.
+  /// This function will return true if the flag was not set before, otherwise
+  /// it will return false. In either case the flag is set afterwards.
+  static bool testAndSet() {
+    static uint32_t DoOnceFlag = 0;
+    return 1 != atomic::exchange(&DoOnceFlag, 1, __ATOMIC_ACQ_REL);
+  }
+};
+} // namespace
+
+/// Helper to hide the __COUNTER__ use away.
+#define SingletonFlag SingletonFlagImpl<__COUNTER__>
+
 #define OMP_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
 #define OMP_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
 

diff  --git a/openmp/libomptarget/DeviceRTL/src/Synchronization.cpp b/openmp/libomptarget/DeviceRTL/src/Synchronization.cpp
index 6b4bab0bcbb20..c83ece50094aa 100644
--- a/openmp/libomptarget/DeviceRTL/src/Synchronization.cpp
+++ b/openmp/libomptarget/DeviceRTL/src/Synchronization.cpp
@@ -320,6 +320,10 @@ uint64_t atomic::add(uint64_t *Addr, uint64_t V, int Ordering) {
   return impl::atomicAdd(Addr, V, Ordering);
 }
 
+uint32_t atomic::exchange(uint32_t *Addr, uint32_t V, int Ordering) {
+  return impl::atomicExchange(Addr, V, Ordering);
+}
+
 extern "C" {
 void __kmpc_ordered(IdentTy *Loc, int32_t TId) { FunctionTracingRAII(); }
 


        


More information about the Openmp-commits mailing list