forked from OSchip/llvm-project
[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
This commit is contained in:
parent
8f3518e69b
commit
ffb21e7f05
|
@ -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()
|
||||
|
|
|
@ -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) = dlsym(RTLD_NEXT, "omp_get_num_devices"))) {
|
||||
} else if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_devices"))) {
|
||||
return (*fptr)();
|
||||
} 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");
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 @@ finish: // Clean up and exit.
|
|||
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");
|
||||
|
|
Loading…
Reference in New Issue