Skip to content

Commit 9b2ef1b

Browse files
committed
xl: Use C11 builtin atomics if available.
If unavailable, fallback to gcc builtins. Some configury work was needed to force include stdatomic.h. Currently xl doesn't have it in its search path. Tested with xl V16.1.1. Signed-off-by: Austen Lauria <[email protected]>
1 parent 4f81935 commit 9b2ef1b

File tree

10 files changed

+162
-427
lines changed

10 files changed

+162
-427
lines changed

config/opal_setup_cc.m4

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,46 @@ AC_DEFUN([OPAL_PROG_CC_C11_HELPER],[
4747

4848
opal_prog_cc_c11_helper_CFLAGS_save=$CFLAGS
4949
CFLAGS="$CFLAGS $1"
50+
OPAL_C_COMPILER_VENDOR([opal_c_vendor])
5051

5152
OPAL_CC_HELPER([if $CC $1 supports C11 _Thread_local], [opal_prog_cc_c11_helper__Thread_local_available],
5253
[],[[static _Thread_local int foo = 1;++foo;]])
5354

55+
56+
OPAL_CC_HELPER([if $CC $1 has stdatomic.h], [opal_prog_cc_c11_helper_atomic_has_stdatomic_h],
57+
[[#include <stdatomic.h>]], [])
58+
if test $opal_prog_cc_c11_helper_atomic_has_stdatomic_h -eq 0; then
59+
if test "$opal_cv_c_compiler_vendor" = "ibm"; then
60+
AC_REQUIRE([AC_PROG_GREP])
61+
tmp=`which gcc`
62+
if test $? -eq 0; then
63+
stdatomic_include_path=""
64+
AC_MSG_CHECKING([if gcc has stdatomic.h])
65+
AC_LANG_CONFTEST([AC_LANG_SOURCE([
66+
#include<stdatomic.h>
67+
int main() { }
68+
]
69+
)])
70+
stdatomic_include_path=`gcc -M conftest.c | $GREP stdatomic.h`
71+
if test -z "$stdatomic_include_path"; then
72+
AC_MSG_WARN([stdatomic.h cannot be found. Fallback to C99 atomics.])
73+
else
74+
stdatomic_include_path="${stdatomic_include_path#"${stdatomic_include_path%%[![:space:]]*}"}"
75+
stdatomic_include_path=${stdatomic_include_path%stdatomic.h}
76+
CFLAGS="$CFLAGS -I$stdatomic_include_path"
77+
opal_prog_cc_c11_helper_CFLAGS_save="$opal_prog_cc_c11_helper_CFLAGS -I$stdatomic_include_path"
78+
opal_prog_cc_c11_helper_atomic_has_stdatomic_h=1
79+
AC_MSG_RESULT([stdatomic.h is available])
80+
AC_MSG_RESULT([Adding $stdatomic_include_path to include path. Using C11 atomics.])
81+
fi
82+
else
83+
AC_MSG_WARN([No gcc found. Not checking for stdatomic.h include. Fallback to C99 atomics.])
84+
fi
85+
else
86+
AC_MSG_WARN([Not checking for gcc stdatomic.h include. Fallback to C99 atomics.])
87+
fi
88+
fi
89+
5490
OPAL_CC_HELPER([if $CC $1 supports C11 atomic variables], [opal_prog_cc_c11_helper_atomic_var_available],
5591
[[#include <stdatomic.h>]], [[static atomic_long foo = 1;++foo;]])
5692

@@ -65,9 +101,9 @@ AC_DEFUN([OPAL_PROG_CC_C11_HELPER],[
65101

66102
OPAL_CC_HELPER([if $CC $1 supports C11 atomic_fetch_xor_explicit], [opal_prog_cc_c11_helper_atomic_fetch_xor_explicit_available],
67103
[[#include <stdatomic.h>
68-
#include <stdint.h>]],[[_Atomic uint32_t a; uint32_t b; atomic_fetch_xor_explicit(&a, b, memory_order_relaxed);]])
104+
#include <stdint.h>]],[[_Atomic uint32_t a; uint32_t b; atomic_fetch_xor_explicit(&a, b, memory_order_relaxed);]])
69105

70-
AS_IF([test $opal_prog_cc_c11_helper__Thread_local_available -eq 1 && test $opal_prog_cc_c11_helper_atomic_var_available -eq 1 && test $opal_prog_cc_c11_helper_atomic_fetch_xor_explicit_available -eq 1],
106+
AS_IF([test $opal_prog_cc_c11_helper__Thread_local_available -eq 1 && test $opal_prog_cc_c11_helper_atomic_var_available -eq 1],
71107
[$2],
72108
[$3])
73109

@@ -166,7 +202,7 @@ AC_DEFUN([OPAL_SETUP_CC],[
166202
if test $opal_cv_c11_supported = no ; then
167203
# It is not currently an error if C11 support is not available. Uncomment the
168204
# following lines and update the warning when we require a C11 compiler.
169-
# AC_MSG_WARNING([Open MPI requires a C11 (or newer) compiler])
205+
# AC_MSG_WARN([Open MPI requires a C11 (or newer) compiler])
170206
# AC_MSG_ERROR([Aborting.])
171207
# From Open MPI 1.7 on we require a C99 compiant compiler
172208
AC_PROG_CC_C99
@@ -287,16 +323,20 @@ AC_DEFUN([OPAL_SETUP_CC],[
287323
OPAL_CFLAGS_BEFORE_PICKY="$CFLAGS"
288324

289325
if test $WANT_PICKY_COMPILER -eq 1; then
290-
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wundef, Wundef)
326+
if test "$opal_cv_c_compiler_vendor" != "portland group"; then
327+
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wundef, Wundef)
328+
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wmissing-prototypes, Wmissing_prototypes)
329+
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wstrict-prototypes, Wstrict_prototypes)
330+
fi
291331
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wno-long-long, Wno_long_long, int main() { long long x; })
292332
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wsign-compare, Wsign_compare)
293-
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wmissing-prototypes, Wmissing_prototypes)
294-
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wstrict-prototypes, Wstrict_prototypes)
295333
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wcomment, Wcomment)
296334
_OPAL_CHECK_SPECIFIC_CFLAGS(-Werror-implicit-function-declaration, Werror_implicit_function_declaration)
297335
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wno-long-double, Wno_long_double, int main() { long double x; })
298336
_OPAL_CHECK_SPECIFIC_CFLAGS(-fno-strict-aliasing, fno_strict_aliasing, int main() { long double x; })
299-
_OPAL_CHECK_SPECIFIC_CFLAGS(-pedantic, pedantic)
337+
if test "$opal_cv_c_compiler_vendor" != "ibm" && test "$opal_cv_c_compiler_vendor" != "portland group"; then
338+
_OPAL_CHECK_SPECIFIC_CFLAGS(-pedantic, pedantic)
339+
fi
300340
_OPAL_CHECK_SPECIFIC_CFLAGS(-Wall, Wall)
301341
fi
302342

ompi/mca/osc/rdma/osc_rdma_active_target.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,20 @@ static void ompi_osc_rdma_check_posts (ompi_osc_rdma_module_t *module)
240240
}
241241
}
242242

243+
#if defined(__ibmxl__)
244+
// Work around an xl optimization bug that would cause the compiler to segv.
245+
//
246+
// xl doesn't like something about caching and checking the return value of
247+
// ompi_osc_rdma_lock_compare_exchange() below when the opt-level is high.
248+
// For now work around this bug by lowering the optimization on this function
249+
// with xl compilers.
250+
//
251+
// Found on:
252+
// $. xlc --version
253+
// IBM XL C/C++ for Linux, V16.1.1 (5725-C73, 5765-J13)
254+
// Version: 16.01.0001.0008
255+
#pragma option_override(ompi_osc_rdma_post_peer, "opt(level,0)")
256+
#endif
243257
static int ompi_osc_rdma_post_peer (ompi_osc_rdma_module_t *module, ompi_osc_rdma_peer_t *peer)
244258
{
245259
uint64_t target = (uint64_t) (intptr_t) peer->state + offsetof (ompi_osc_rdma_state_t, post_index);

opal/include/opal/opal_portable_platform.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
# else
181181
# define PLATFORM_COMPILER_XLC_C 1
182182
# endif
183-
# define PLATFORM_COMPILER_VERSION __xlC__
183+
# define PLATFORM_COMPILER_VERSION __ibmxl_version__
184184
# define PLATFORM_COMPILER_VERSION_INT(maj,min,pat) \
185185
( ((maj) << 8) | ((min) << 4) | (pat) )
186186

opal/include/opal/sys/atomic.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ BEGIN_C_DECLS
9797
* to use an int or unsigned char as the lock value - the user is not
9898
* informed either way.
9999
*/
100+
#ifndef OPAL_USE_ATOMIC_FLAG_OPAL_LOCK
100101
struct opal_atomic_lock_t {
101102
union {
102103
opal_atomic_int32_t lock; /**< The lock address (an integer) */
@@ -105,7 +106,7 @@ struct opal_atomic_lock_t {
105106
} u;
106107
};
107108
typedef struct opal_atomic_lock_t opal_atomic_lock_t;
108-
109+
#endif
109110
/**********************************************************************
110111
*
111112
* Set or unset these macros in the architecture-specific atomic.h
@@ -164,7 +165,7 @@ enum {
164165
*********************************************************************/
165166
#if defined(DOXYGEN)
166167
/* don't include system-level gorp when generating doxygen files */
167-
#elif OPAL_ASSEMBLY_BUILTIN == OPAL_BUILTIN_GCC
168+
#elif OPAL_ASSEMBLY_BUILTIN == OPAL_BUILTIN_GCC || OPAL_ASSEMBLY_ARCH == OPAL_POWERPC32 || OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64
168169
#include "opal/sys/gcc_builtin/atomic.h"
169170
#elif OPAL_ASSEMBLY_ARCH == OPAL_X86_64
170171
#include "opal/sys/x86_64/atomic.h"
@@ -174,10 +175,6 @@ enum {
174175
#include "opal/sys/arm64/atomic.h"
175176
#elif OPAL_ASSEMBLY_ARCH == OPAL_IA32
176177
#include "opal/sys/ia32/atomic.h"
177-
#elif OPAL_ASSEMBLY_ARCH == OPAL_POWERPC32
178-
#include "opal/sys/powerpc/atomic.h"
179-
#elif OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64
180-
#include "opal/sys/powerpc/atomic.h"
181178
#endif
182179

183180
#ifndef DOXYGEN

opal/include/opal/sys/atomic_stdc.h

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,28 @@ static inline void opal_atomic_rmb (void)
9797
#define opal_atomic_compare_exchange_strong_acq(addr, oldval, newval) atomic_compare_exchange_strong_explicit (addr, oldval, newval, memory_order_acquire, memory_order_relaxed)
9898
#define opal_atomic_compare_exchange_strong_rel(addr, oldval, newval) atomic_compare_exchange_strong_explicit (addr, oldval, newval, memory_order_release, memory_order_relaxed)
9999

100+
#if defined(__PGI) || defined(__ibmxl__)
101+
#define opal_atomic_swap_32(addr, value) atomic_exchange_explicit (addr, value, memory_order_relaxed)
102+
#define opal_atomic_swap_64(addr, value) atomic_exchange_explicit (addr, value, memory_order_relaxed)
103+
#define opal_atomic_swap_ptr(addr, value) atomic_exchange_explicit (addr, value, memory_order_relaxed)
104+
#else
100105
#define opal_atomic_swap_32(addr, value) atomic_exchange_explicit ((_Atomic unsigned int *)addr, value, memory_order_relaxed)
101106
#define opal_atomic_swap_64(addr, value) atomic_exchange_explicit ((_Atomic unsigned long *)addr, value, memory_order_relaxed)
102107
#define opal_atomic_swap_ptr(addr, value) atomic_exchange_explicit ((_Atomic unsigned long *)addr, value, memory_order_relaxed)
108+
#endif
103109

110+
#if defined(__PGI) || defined(__ibmxl__)
111+
#define OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(op, bits, type, operator) \
112+
static inline type opal_atomic_fetch_ ## op ##_## bits (opal_atomic_ ## type *addr, type value) \
113+
{ \
114+
return atomic_fetch_ ## op ## _explicit ((type *)addr, value, memory_order_relaxed); \
115+
} \
116+
\
117+
static inline type opal_atomic_## op ## _fetch_ ## bits (opal_atomic_ ## type *addr, type value) \
118+
{ \
119+
return atomic_fetch_ ## op ## _explicit ((type *)addr, value, memory_order_relaxed) operator value; \
120+
}
121+
#else
104122
#define OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(op, bits, type, operator) \
105123
static inline type opal_atomic_fetch_ ## op ##_## bits (opal_atomic_ ## type *addr, type value) \
106124
{ \
@@ -111,6 +129,7 @@ static inline void opal_atomic_rmb (void)
111129
{ \
112130
return atomic_fetch_ ## op ## _explicit (addr, value, memory_order_relaxed) operator value; \
113131
}
132+
#endif
114133

115134
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, 32, int32_t, +)
116135
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, 64, int64_t, +)
@@ -206,22 +225,39 @@ static inline int64_t opal_atomic_max_fetch_64 (opal_atomic_int64_t *addr, int64
206225
#define OPAL_ATOMIC_LOCK_UNLOCKED false
207226
#define OPAL_ATOMIC_LOCK_LOCKED true
208227

209-
#define OPAL_ATOMIC_LOCK_INIT ATOMIC_FLAG_INIT
228+
#define OPAL_USE_C11_ATOMIC_LOCK 1
210229

230+
#define OPAL_USE_ATOMIC_FLAG_OPAL_LOCK 1
231+
#if defined(__ibmxl__) || defined(__PGI)
232+
#define OPAL_ATOMIC_LOCK_INIT 0
233+
typedef _Atomic bool opal_atomic_lock_t;
234+
#else
235+
#define OPAL_ATOMIC_LOCK_INIT ATOMIC_FLAG_INIT
211236
typedef atomic_flag opal_atomic_lock_t;
237+
#endif
212238

213239
/*
214240
* Lock initialization function. It set the lock to UNLOCKED.
215241
*/
216242
static inline void opal_atomic_lock_init (opal_atomic_lock_t *lock, bool value)
217243
{
244+
#if defined(__PGI)
245+
atomic_flag_clear ((volatile void *) lock);
246+
#else
218247
atomic_flag_clear (lock);
248+
#endif
219249
}
220250

221251

222252
static inline int opal_atomic_trylock (opal_atomic_lock_t *lock)
223253
{
254+
255+
#if defined(__PGI)
256+
return (int) atomic_flag_test_and_set ((volatile void *) lock);
257+
#else
224258
return (int) atomic_flag_test_and_set (lock);
259+
#endif
260+
225261
}
226262

227263

@@ -234,7 +270,11 @@ static inline void opal_atomic_lock(opal_atomic_lock_t *lock)
234270

235271
static inline void opal_atomic_unlock (opal_atomic_lock_t *lock)
236272
{
273+
#if defined(__PGI)
274+
atomic_flag_clear ((volatile void *) lock);
275+
#else
237276
atomic_flag_clear (lock);
277+
#endif
238278
}
239279

240280

opal/include/opal/sys/powerpc/Makefile.am

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,4 @@
1919
# This makefile.am does not stand on its own - it is included from opal/include/Makefile.am
2020

2121
headers += \
22-
opal/sys/powerpc/atomic.h \
2322
opal/sys/powerpc/timer.h

0 commit comments

Comments
 (0)