Skip to content

[openmp][wasm] Allow compiling OpenMP to WebAssembly #71297

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4982,10 +4982,13 @@ OpenMPIRBuilder::getOrCreateInternalVariable(Type *Ty, const StringRef &Name,
// variable for possibly changing that to internal or private, or maybe
// create different versions of the function for different OMP internal
// variables.
auto *GV = new GlobalVariable(
M, Ty, /*IsConstant=*/false, GlobalValue::CommonLinkage,
Constant::getNullValue(Ty), Elem.first(),
/*InsertBefore=*/nullptr, GlobalValue::NotThreadLocal, AddressSpace);
auto Linkage = this->M.getTargetTriple().rfind("wasm32") == 0
? GlobalValue::ExternalLinkage
: GlobalValue::CommonLinkage;
Copy link
Contributor

@arsnyder16 arsnyder16 Jun 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abrown Hey Andrew, this seems to break linking under wasm.

Previously when it common linked it was required to define these variables through assembly, hence you updates to z_Linux_asm.S specially .global .gomp_critical_user_.reduction.var are actually no longer required.

But now that they are external linkage they suffer from duplicate symbol problem.

For critical sections this can avoided if you manually add a name to the critical section that does not conflict
omp critical(UniqueValue)

but for reduction allowing them to be named is not an option, so if multiple compilation units use reduction you will introduce a duplicate symbols

wasm-ld: error: duplicate symbol: .gomp_critical_user_.reduction.var
>>> defined in lib/libTest.a(a.cpp.o)
>>> defined in lib/libTest.a(b.cpp.o)

I am wonder if something like InternalLinkage is more appropriate

auto *GV = new GlobalVariable(M, Ty, /*IsConstant=*/false, Linkage,
Constant::getNullValue(Ty), Elem.first(),
/*InsertBefore=*/nullptr,
GlobalValue::NotThreadLocal, AddressSpace);
const DataLayout &DL = M.getDataLayout();
const llvm::Align TypeAlign = DL.getABITypeAlign(Ty);
const llvm::Align PtrAlign = DL.getPointerABIAlignment(AddressSpace);
Expand Down
2 changes: 1 addition & 1 deletion openmp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ set(ENABLE_LIBOMPTARGET ON)
# Since the device plugins are only supported on Linux anyway,
# there is no point in trying to compile libomptarget on other OSes.
# 32-bit systems are not supported either.
if (APPLE OR WIN32 OR NOT "cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES OR NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
if (APPLE OR WIN32 OR WASM OR NOT "cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES OR NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
set(ENABLE_LIBOMPTARGET OFF)
endif()

Expand Down
14 changes: 12 additions & 2 deletions openmp/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ if(${OPENMP_STANDALONE_BUILD})
# If adding a new architecture, take a look at cmake/LibompGetArchitecture.cmake
libomp_get_architecture(LIBOMP_DETECTED_ARCH)
set(LIBOMP_ARCH ${LIBOMP_DETECTED_ARCH} CACHE STRING
"The architecture to build for (x86_64/i386/arm/ppc64/ppc64le/aarch64/mic/mips/mips64/riscv64/loongarch64/ve/s390x).")
"The architecture to build for (x86_64/i386/arm/ppc64/ppc64le/aarch64/mic/mips/mips64/riscv64/loongarch64/ve/s390x/wasm32).")
# Should assertions be enabled? They are on by default.
set(LIBOMP_ENABLE_ASSERTIONS TRUE CACHE BOOL
"enable assertions?")
Expand Down Expand Up @@ -67,6 +67,8 @@ else() # Part of LLVM build
set(LIBOMP_ARCH ve)
elseif(LIBOMP_NATIVE_ARCH MATCHES "s390x")
set(LIBOMP_ARCH s390x)
elseif(LIBOMP_NATIVE_ARCH MATCHES "wasm")
set(LIBOMP_ARCH wasm32)
else()
# last ditch effort
libomp_get_architecture(LIBOMP_ARCH)
Expand All @@ -87,7 +89,7 @@ if(LIBOMP_ARCH STREQUAL "aarch64")
endif()
endif()

libomp_check_variable(LIBOMP_ARCH 32e x86_64 32 i386 arm ppc64 ppc64le aarch64 aarch64_a64fx mic mips mips64 riscv64 loongarch64 ve s390x)
libomp_check_variable(LIBOMP_ARCH 32e x86_64 32 i386 arm ppc64 ppc64le aarch64 aarch64_a64fx mic mips mips64 riscv64 loongarch64 ve s390x wasm32)

set(LIBOMP_LIB_TYPE normal CACHE STRING
"Performance,Profiling,Stubs library (normal/profile/stubs)")
Expand Down Expand Up @@ -168,6 +170,7 @@ set(RISCV64 FALSE)
set(LOONGARCH64 FALSE)
set(VE FALSE)
set(S390X FALSE)
set(WASM FALSE)
if("${LIBOMP_ARCH}" STREQUAL "i386" OR "${LIBOMP_ARCH}" STREQUAL "32") # IA-32 architecture
set(IA32 TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "x86_64" OR "${LIBOMP_ARCH}" STREQUAL "32e") # Intel(R) 64 architecture
Expand Down Expand Up @@ -198,6 +201,8 @@ elseif("${LIBOMP_ARCH}" STREQUAL "ve") # VE architecture
set(VE TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "s390x") # S390x (Z) architecture
set(S390X TRUE)
elseif("${LIBOMP_ARCH}" STREQUAL "wasm32") # WebAssembly architecture
set(WASM TRUE)
endif()

# Set some flags based on build_type
Expand Down Expand Up @@ -306,6 +311,11 @@ endif()
set(LIBOMP_ENABLE_SHARED TRUE CACHE BOOL
"Shared library instead of static library?")

if(WASM)
libomp_warning_say("The WebAssembly build currently only supports static libraries; forcing LIBOMP_ENABLE_SHARED to false")
set(LIBOMP_ENABLE_SHARED FALSE)
endif()

if(WIN32 AND NOT LIBOMP_ENABLE_SHARED)
libomp_error_say("Static libraries requested but not available on Windows")
endif()
Expand Down
2 changes: 2 additions & 0 deletions openmp/runtime/cmake/LibompGetArchitecture.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ function(libomp_get_architecture return_arch)
#error ARCHITECTURE=ve
#elif defined(__s390x__)
#error ARCHITECTURE=s390x
#elif defined(__wasm32__)
#error ARCHITECTURE=wasm32
#else
#error ARCHITECTURE=UnknownArchitecture
#endif
Expand Down
23 changes: 14 additions & 9 deletions openmp/runtime/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,20 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_C_COMPILER_ID STREQUAL "IntelLL
check_library_exists(irc_pic _intel_fast_memcpy "" LIBOMP_HAVE_IRC_PIC_LIBRARY)
endif()

# Checking Threading requirements
find_package(Threads REQUIRED)
if(WIN32)
if(NOT CMAKE_USE_WIN32_THREADS_INIT)
libomp_error_say("Need Win32 thread interface on Windows.")
endif()
else()
if(NOT CMAKE_USE_PTHREADS_INIT)
libomp_error_say("Need pthread interface on Unix-like systems.")
# Checking threading requirements. Note that compiling to WebAssembly threads
# with either the Emscripten or wasi-threads flavor ends up using the pthreads
# interface in a WebAssembly-compiled libc; CMake does not yet know how to
# detect this.
if (NOT WASM)
find_package(Threads REQUIRED)
if(WIN32)
if(NOT CMAKE_USE_WIN32_THREADS_INIT)
libomp_error_say("Need Win32 thread interface on Windows.")
endif()
else()
if(NOT CMAKE_USE_PTHREADS_INIT)
libomp_error_say("Need pthread interface on Unix-like systems.")
endif()
endif()
endif()

Expand Down
16 changes: 15 additions & 1 deletion openmp/runtime/src/kmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,15 @@
#undef KMP_CANCEL_THREADS
#endif

// Some WASI targets (e.g., wasm32-wasi-threads) do not support thread
// cancellation.
#if KMP_OS_WASI
#undef KMP_CANCEL_THREADS
#endif

#if !KMP_OS_WASI
#include <signal.h>
#endif
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
Expand Down Expand Up @@ -124,7 +132,7 @@ class kmp_stats_list;
#endif
#include "kmp_i18n.h"

#define KMP_HANDLE_SIGNALS (KMP_OS_UNIX || KMP_OS_WINDOWS)
#define KMP_HANDLE_SIGNALS ((KMP_OS_UNIX && !KMP_OS_WASI) || KMP_OS_WINDOWS)

#include "kmp_wrapper_malloc.h"
#if KMP_OS_UNIX
Expand Down Expand Up @@ -601,7 +609,9 @@ typedef int PACKED_REDUCTION_METHOD_T;
#endif

#if KMP_OS_UNIX
#if !KMP_OS_WASI
#include <dlfcn.h>
#endif
#include <pthread.h>
#endif

Expand Down Expand Up @@ -1340,6 +1350,10 @@ extern kmp_uint64 __kmp_now_nsec();
/* TODO: tune for KMP_OS_SOLARIS */
#define KMP_INIT_WAIT 1024U /* initial number of spin-tests */
#define KMP_NEXT_WAIT 512U /* susequent number of spin-tests */
#elif KMP_OS_WASI
/* TODO: tune for KMP_OS_WASI */
#define KMP_INIT_WAIT 1024U /* initial number of spin-tests */
#define KMP_NEXT_WAIT 512U /* susequent number of spin-tests */
#endif

#if KMP_ARCH_X86 || KMP_ARCH_X86_64
Expand Down
18 changes: 9 additions & 9 deletions openmp/runtime/src/kmp_ftn_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)(void) {
return 0;
}
--gtid; // We keep (gtid+1) in TLS
#elif KMP_OS_LINUX
#elif KMP_OS_LINUX || KMP_OS_WASI
#ifdef KMP_TDATA_GTID
if (__kmp_gtid_mode >= 3) {
if ((gtid = __kmp_gtid) == KMP_GTID_DNE) {
Expand Down Expand Up @@ -1043,7 +1043,7 @@ void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) {
int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void)
KMP_WEAK_ATTRIBUTE_EXTERNAL;
int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void) {
#if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_MIC || KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return 0;
#else
int (*fptr)();
Expand Down Expand Up @@ -1558,7 +1558,7 @@ typedef void *omp_interop_t;

// libomptarget, if loaded, provides this function
int FTN_STDCALL FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop) {
#if KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return 0;
#else
int (*fptr)(const omp_interop_t);
Expand All @@ -1573,7 +1573,7 @@ int FTN_STDCALL FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop) {
intptr_t FTN_STDCALL FTN_GET_INTEROP_INT(const omp_interop_t interop,
omp_interop_property_t property_id,
int *err) {
#if KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return 0;
#else
intptr_t (*fptr)(const omp_interop_t, omp_interop_property_t, int *);
Expand All @@ -1587,7 +1587,7 @@ intptr_t FTN_STDCALL FTN_GET_INTEROP_INT(const omp_interop_t interop,
void *FTN_STDCALL FTN_GET_INTEROP_PTR(const omp_interop_t interop,
omp_interop_property_t property_id,
int *err) {
#if KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return nullptr;
#else
void *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);
Expand All @@ -1601,7 +1601,7 @@ void *FTN_STDCALL FTN_GET_INTEROP_PTR(const omp_interop_t interop,
const char *FTN_STDCALL FTN_GET_INTEROP_STR(const omp_interop_t interop,
omp_interop_property_t property_id,
int *err) {
#if KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return nullptr;
#else
const char *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);
Expand All @@ -1614,7 +1614,7 @@ const char *FTN_STDCALL FTN_GET_INTEROP_STR(const omp_interop_t interop,
// libomptarget, if loaded, provides this function
const char *FTN_STDCALL FTN_GET_INTEROP_NAME(
const omp_interop_t interop, omp_interop_property_t property_id) {
#if KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return nullptr;
#else
const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
Expand All @@ -1627,7 +1627,7 @@ const char *FTN_STDCALL FTN_GET_INTEROP_NAME(
// libomptarget, if loaded, provides this function
const char *FTN_STDCALL FTN_GET_INTEROP_TYPE_DESC(
const omp_interop_t interop, omp_interop_property_t property_id) {
#if KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return nullptr;
#else
const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
Expand All @@ -1640,7 +1640,7 @@ const char *FTN_STDCALL FTN_GET_INTEROP_TYPE_DESC(
// libomptarget, if loaded, provides this function
const char *FTN_STDCALL FTN_GET_INTEROP_RC_DESC(
const omp_interop_t interop, omp_interop_property_t property_id) {
#if KMP_OS_DARWIN || defined(KMP_STUB)
#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return nullptr;
#else
const char *(*fptr)(const omp_interop_t, omp_interop_property_t);
Expand Down
2 changes: 1 addition & 1 deletion openmp/runtime/src/kmp_gsupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_ORDERED_END)(void) {
// They come in two flavors: 64-bit unsigned, and either 32-bit signed
// (IA-32 architecture) or 64-bit signed (Intel(R) 64).

#if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS
#if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS || KMP_ARCH_WASM
#define KMP_DISPATCH_INIT __kmp_aux_dispatch_init_4
#define KMP_DISPATCH_FINI_CHUNK __kmp_aux_dispatch_fini_chunk_4
#define KMP_DISPATCH_NEXT __kmpc_dispatch_next_4
Expand Down
15 changes: 9 additions & 6 deletions openmp/runtime/src/kmp_os.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
#error Unknown compiler
#endif

#if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD)
#if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD) && !KMP_OS_WASI
#define KMP_AFFINITY_SUPPORTED 1
#if KMP_OS_WINDOWS && KMP_ARCH_X86_64
#define KMP_GROUP_AFFINITY 1
Expand Down Expand Up @@ -176,7 +176,7 @@ typedef unsigned long long kmp_uint64;
#define KMP_UINT64_SPEC "llu"
#endif /* KMP_OS_UNIX */

#if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS
#if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS || KMP_ARCH_WASM
#define KMP_SIZE_T_SPEC KMP_UINT32_SPEC
#elif KMP_ARCH_X86_64 || KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || \
KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64 || KMP_ARCH_LOONGARCH64 || \
Expand All @@ -186,7 +186,7 @@ typedef unsigned long long kmp_uint64;
#error "Can't determine size_t printf format specifier."
#endif

#if KMP_ARCH_X86 || KMP_ARCH_ARM
#if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_WASM
#define KMP_SIZE_T_MAX (0xFFFFFFFF)
#else
#define KMP_SIZE_T_MAX (0xFFFFFFFFFFFFFFFF)
Expand Down Expand Up @@ -215,8 +215,8 @@ typedef kmp_uint32 kmp_uint;
#define KMP_INT_MIN ((kmp_int32)0x80000000)

// stdarg handling
#if (KMP_ARCH_ARM || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64) && \
(KMP_OS_FREEBSD || KMP_OS_LINUX)
#if (KMP_ARCH_ARM || KMP_ARCH_X86_64 || KMP_ARCH_AARCH64 || KMP_ARCH_WASM) && \
(KMP_OS_FREEBSD || KMP_OS_LINUX || KMP_OS_WASI)
typedef va_list *kmp_va_list;
#define kmp_va_deref(ap) (*(ap))
#define kmp_va_addr_of(ap) (&(ap))
Expand Down Expand Up @@ -1146,7 +1146,7 @@ extern kmp_real64 __kmp_xchg_real64(volatile kmp_real64 *p, kmp_real64 v);
KMP_COMPARE_AND_STORE_REL64((volatile kmp_int64 *)(volatile void *)&(a), \
(kmp_int64)(b), (kmp_int64)(c))

#if KMP_ARCH_X86 || KMP_ARCH_MIPS
#if KMP_ARCH_X86 || KMP_ARCH_MIPS || KMP_ARCH_WASM
// What about ARM?
#define TCR_PTR(a) ((void *)TCR_4(a))
#define TCW_PTR(a, b) TCW_4((a), (b))
Expand Down Expand Up @@ -1288,6 +1288,9 @@ bool __kmp_atomic_compare_store_rel(std::atomic<T> *p, T expected, T desired) {
extern void *__kmp_lookup_symbol(const char *name, bool next = false);
#define KMP_DLSYM(name) __kmp_lookup_symbol(name)
#define KMP_DLSYM_NEXT(name) __kmp_lookup_symbol(name, true)
#elif KMP_OS_WASI
#define KMP_DLSYM(name) nullptr
#define KMP_DLSYM_NEXT(name) nullptr
#else
#define KMP_DLSYM(name) dlsym(RTLD_DEFAULT, name)
#define KMP_DLSYM_NEXT(name) dlsym(RTLD_NEXT, name)
Expand Down
20 changes: 16 additions & 4 deletions openmp/runtime/src/kmp_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define KMP_OS_WINDOWS 0
#define KMP_OS_HURD 0
#define KMP_OS_SOLARIS 0
#define KMP_OS_WASI 0
#define KMP_OS_UNIX 0 /* disjunction of KMP_OS_LINUX, KMP_OS_DARWIN etc. */

#ifdef _WIN32
Expand Down Expand Up @@ -76,14 +77,20 @@
#define KMP_OS_SOLARIS 1
#endif

#if (defined __wasi__) || (defined __EMSCRIPTEN__)
Copy link
Contributor

@arsnyder16 arsnyder16 Jun 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abrown
This is conflating wasi and the emscripten toolchain. They are two different cases where emscripten mimics linux/posix system by statically linking musl into the wasm file. This was mentioned in D142593

The changes in this PR will not allow openmp to compile under emscripten, the changes here will
#95169

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good finds, both of them. Let's discuss in #95169.

#undef KMP_OS_WASI
#define KMP_OS_WASI 1
#endif

#if (1 != KMP_OS_LINUX + KMP_OS_DRAGONFLY + KMP_OS_FREEBSD + KMP_OS_NETBSD + \
KMP_OS_OPENBSD + KMP_OS_DARWIN + KMP_OS_WINDOWS + KMP_OS_HURD + \
KMP_OS_SOLARIS)
KMP_OS_SOLARIS + KMP_OS_WASI)
#error Unknown OS
#endif

#if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
KMP_OS_OPENBSD || KMP_OS_DARWIN || KMP_OS_HURD || KMP_OS_SOLARIS
KMP_OS_OPENBSD || KMP_OS_DARWIN || KMP_OS_HURD || KMP_OS_SOLARIS || \
KMP_OS_WASI
#undef KMP_OS_UNIX
#define KMP_OS_UNIX 1
#endif
Expand Down Expand Up @@ -196,6 +203,10 @@
#define KMP_ARCH_ARM 1
#endif

#if defined(__wasm32__)
#define KMP_ARCH_WASM 1
#endif

#if defined(__MIC__) || defined(__MIC2__)
#define KMP_MIC 1
#if __MIC2__ || __KNC__
Expand All @@ -212,7 +223,8 @@
#endif

/* Specify 32 bit architectures here */
#define KMP_32_BIT_ARCH (KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS)
#define KMP_32_BIT_ARCH \
(KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS || KMP_ARCH_WASM)

// Platforms which support Intel(R) Many Integrated Core Architecture
#define KMP_MIC_SUPPORTED \
Expand All @@ -222,7 +234,7 @@
#if (1 != KMP_ARCH_X86 + KMP_ARCH_X86_64 + KMP_ARCH_ARM + KMP_ARCH_PPC64 + \
KMP_ARCH_AARCH64 + KMP_ARCH_MIPS + KMP_ARCH_MIPS64 + \
KMP_ARCH_RISCV64 + KMP_ARCH_LOONGARCH64 + KMP_ARCH_VE + \
KMP_ARCH_S390X)
KMP_ARCH_S390X + KMP_ARCH_WASM)
#error Unknown or unsupported architecture
#endif

Expand Down
Loading