Skip to content

Commit

Permalink
[OpenMP] Ensure broken assumptions print once, not thousands of times.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jhuber6 committed Jan 27, 2022
1 parent 2945f11 commit 27c799e
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
6 changes: 4 additions & 2 deletions openmp/libomptarget/DeviceRTL/include/Debug.h
Expand Up @@ -13,6 +13,7 @@
#define OMPTARGET_DEVICERTL_DEBUG_H

#include "Configuration.h"
#include "Utils.h"

/// Assertion
///
Expand All @@ -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); \
}

Expand Down
4 changes: 4 additions & 0 deletions openmp/libomptarget/DeviceRTL/include/Synchronization.h
Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions openmp/libomptarget/DeviceRTL/include/Utils.h
Expand Up @@ -12,6 +12,7 @@
#ifndef OMPTARGET_DEVICERTL_UTILS_H
#define OMPTARGET_DEVICERTL_UTILS_H

#include "Synchronization.h"
#include "Types.h"

namespace _OMP {
Expand Down Expand Up @@ -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)

Expand Down
4 changes: 4 additions & 0 deletions openmp/libomptarget/DeviceRTL/src/Synchronization.cpp
Expand Up @@ -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(); }

Expand Down

0 comments on commit 27c799e

Please sign in to comment.