[Openmp-commits] [openmp] ffb21e7 - [OpenMP] Enable omp_get_num_devices() on Windows
Hansang Bae via Openmp-commits
openmp-commits at lists.llvm.org
Thu Feb 11 13:08:40 PST 2021
Author: Hansang Bae
Date: 2021-02-11T14:53:48-06:00
New Revision: ffb21e7f0593fde83568ae364040296fe94cf347
URL: https://github.com/llvm/llvm-project/commit/ffb21e7f0593fde83568ae364040296fe94cf347
DIFF: https://github.com/llvm/llvm-project/commit/ffb21e7f0593fde83568ae364040296fe94cf347.diff
LOG: [OpenMP] Enable omp_get_num_devices() on Windows
This patch enables omp_get_num_devices() and omp_get_initial_device() on
Windows by providing an alternative to dlsym on Windows, and proposes to
add a new libomptarget entry, __tgt_get_num_devices().
Differential Revision: https://reviews.llvm.org/D96182
Added:
Modified:
openmp/runtime/cmake/LibompHandleFlags.cmake
openmp/runtime/src/kmp_ftn_entry.h
openmp/runtime/src/kmp_os.h
openmp/runtime/src/z_Windows_NT_util.cpp
Removed:
################################################################################
diff --git a/openmp/runtime/cmake/LibompHandleFlags.cmake b/openmp/runtime/cmake/LibompHandleFlags.cmake
index 4a25359a788c..82a2e884bc41 100644
--- a/openmp/runtime/cmake/LibompHandleFlags.cmake
+++ b/openmp/runtime/cmake/LibompHandleFlags.cmake
@@ -126,6 +126,9 @@ function(libomp_get_libflags libflags)
if(${IA32})
libomp_append(libflags_local -lirc_pic LIBOMP_HAVE_IRC_PIC_LIBRARY)
endif()
+ if(MINGW)
+ libomp_append(libflags_local -lpsapi LIBOMP_HAVE_LIBPSAPI)
+ endif()
if(LIBOMP_HAVE_SHM_OPEN_WITH_LRT)
libomp_append(libflags_local -lrt)
endif()
diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h
index cf44019f94be..935feacc34f2 100644
--- a/openmp/runtime/src/kmp_ftn_entry.h
+++ b/openmp/runtime/src/kmp_ftn_entry.h
@@ -941,13 +941,15 @@ void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) {
// libomptarget, if loaded, provides this function in api.cpp.
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 || KMP_OS_WINDOWS || defined(KMP_STUB)
+#if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)
return 0;
#else
int (*fptr)();
- if ((*(void **)(&fptr) = dlsym(RTLD_DEFAULT, "_Offload_number_of_devices"))) {
+ if ((*(void **)(&fptr) = KMP_DLSYM("__tgt_get_num_devices"))) {
+ return (*fptr)();
+ } else if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_devices"))) {
return (*fptr)();
- } else if ((*(void **)(&fptr) = dlsym(RTLD_NEXT, "omp_get_num_devices"))) {
+ } else if ((*(void **)(&fptr) = KMP_DLSYM("_Offload_number_of_devices"))) {
return (*fptr)();
} else { // liboffload & libomptarget don't exist
return 0;
@@ -963,20 +965,11 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) {
}
// libomptarget, if loaded, provides this function
-int FTN_STDCALL FTN_GET_INITIAL_DEVICE(void) KMP_WEAK_ATTRIBUTE_EXTERNAL;
-int FTN_STDCALL FTN_GET_INITIAL_DEVICE(void) {
-#if KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB)
+int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void)
+ KMP_WEAK_ATTRIBUTE_EXTERNAL;
+int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void) {
// same as omp_get_num_devices()
- return 0;
-#else
- int (*fptr)();
- if ((*(void **)(&fptr) = dlsym(RTLD_NEXT, "omp_get_initial_device"))) {
- return (*fptr)();
- } else { // liboffload & libomptarget don't exist
- // same as omp_get_num_devices()
- return 0;
- }
-#endif
+ return KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)();
}
#if defined(KMP_STUB)
@@ -1321,22 +1314,22 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)(void) {
// loaded, we assume we are on the host and return KMP_HOST_DEVICE.
// Compiler/libomptarget will handle this if called inside target.
int FTN_STDCALL FTN_GET_DEVICE_NUM(void) KMP_WEAK_ATTRIBUTE_EXTERNAL;
-int FTN_STDCALL FTN_GET_DEVICE_NUM(void) { return FTN_GET_INITIAL_DEVICE(); }
+int FTN_STDCALL FTN_GET_DEVICE_NUM(void) {
+ return KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)();
+}
// Compiler will ensure that this is only called from host in sequential region
int FTN_STDCALL FTN_PAUSE_RESOURCE(kmp_pause_status_t kind, int device_num) {
#ifdef KMP_STUB
return 1; // just fail
#else
- if (device_num == FTN_GET_INITIAL_DEVICE())
+ if (device_num == KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)())
return __kmpc_pause_resource(kind);
else {
-#if !KMP_OS_WINDOWS
int (*fptr)(kmp_pause_status_t, int);
- if ((*(void **)(&fptr) = dlsym(RTLD_DEFAULT, "tgt_pause_resource")))
+ if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))
return (*fptr)(kind, device_num);
else
-#endif
return 1; // just fail if there is no libomptarget
}
#endif
@@ -1348,11 +1341,9 @@ int FTN_STDCALL FTN_PAUSE_RESOURCE_ALL(kmp_pause_status_t kind) {
return 1; // just fail
#else
int fails = 0;
-#if !KMP_OS_WINDOWS
int (*fptr)(kmp_pause_status_t, int);
- if ((*(void **)(&fptr) = dlsym(RTLD_DEFAULT, "tgt_pause_resource")))
+ if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))
fails = (*fptr)(kind, KMP_DEVICE_ALL); // pause devices
-#endif
fails += __kmpc_pause_resource(kind); // pause host
return fails;
#endif
@@ -1515,7 +1506,7 @@ KMP_VERSION_SYMBOL(FTN_GET_PLACE_PROC_IDS, 45, "OMP_4.5");
KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM, 45, "OMP_4.5");
KMP_VERSION_SYMBOL(FTN_GET_PARTITION_NUM_PLACES, 45, "OMP_4.5");
KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLACE_NUMS, 45, "OMP_4.5");
-// KMP_VERSION_SYMBOL(FTN_GET_INITIAL_DEVICE, 45, "OMP_4.5");
+KMP_VERSION_SYMBOL(FTN_GET_INITIAL_DEVICE, 45, "OMP_4.5");
// OMP_5.0 versioned symbols
// KMP_VERSION_SYMBOL(FTN_GET_DEVICE_NUM, 50, "OMP_5.0");
diff --git a/openmp/runtime/src/kmp_os.h b/openmp/runtime/src/kmp_os.h
index 5ceae9857b32..590a2c710cc9 100644
--- a/openmp/runtime/src/kmp_os.h
+++ b/openmp/runtime/src/kmp_os.h
@@ -1077,6 +1077,16 @@ bool __kmp_atomic_compare_store_rel(std::atomic<T> *p, T expected, T desired) {
expected, desired, std::memory_order_release, std::memory_order_relaxed);
}
+// Symbol lookup on Linux/Windows
+#if KMP_OS_WINDOWS
+extern void *__kmp_lookup_symbol(const char *name);
+#define KMP_DLSYM(name) __kmp_lookup_symbol(name)
+#define KMP_DLSYM_NEXT(name) nullptr
+#else
+#define KMP_DLSYM(name) dlsym(RTLD_DEFAULT, name)
+#define KMP_DLSYM_NEXT(name) dlsym(RTLD_NEXT, name)
+#endif
+
#endif /* KMP_OS_H */
// Safe C API
#include "kmp_safe_c_api.h"
diff --git a/openmp/runtime/src/z_Windows_NT_util.cpp b/openmp/runtime/src/z_Windows_NT_util.cpp
index 551c4146f5f9..7a22df02eb2e 100644
--- a/openmp/runtime/src/z_Windows_NT_util.cpp
+++ b/openmp/runtime/src/z_Windows_NT_util.cpp
@@ -23,6 +23,8 @@
#include <ntsecapi.h> // UNICODE_STRING
#include <ntstatus.h>
+#include <psapi.h>
+#pragma comment(lib, "psapi.lib")
enum SYSTEM_INFORMATION_CLASS {
SystemProcessInformation = 5
@@ -1632,6 +1634,29 @@ int __kmp_get_load_balance(int max) {
return running_threads;
} //__kmp_get_load_balance()
+// Find symbol from the loaded modules
+void *__kmp_lookup_symbol(const char *name) {
+ HANDLE process = GetCurrentProcess();
+ DWORD needed;
+ HMODULE *modules = nullptr;
+ if (!EnumProcessModules(process, modules, 0, &needed))
+ return nullptr;
+ DWORD num_modules = needed / sizeof(HMODULE);
+ modules = (HMODULE *)malloc(num_modules * sizeof(HMODULE));
+ if (!EnumProcessModules(process, modules, needed, &needed)) {
+ free(modules);
+ return nullptr;
+ }
+ void *proc = nullptr;
+ for (uint32_t i = 0; i < num_modules; i++) {
+ proc = (void *)GetProcAddress(modules[i], name);
+ if (proc)
+ break;
+ }
+ free(modules);
+ return proc;
+}
+
// Functions for hidden helper task
void __kmp_hidden_helper_worker_thread_wait() {
KMP_ASSERT(0 && "Hidden helper task is not supported on Windows");
More information about the Openmp-commits
mailing list