summaryrefslogtreecommitdiff
path: root/openmp
diff options
context:
space:
mode:
authorRobert Imschweiler <robert.imschweiler@amd.com>2025-11-18 15:22:49 +0100
committerGitHub <noreply@github.com>2025-11-18 15:22:49 +0100
commit65c4a534bd55ed56962fb99c36f464b3f1c9732f (patch)
treef4b9d0e23ddac320252c3824d0f253f0740b52fb /openmp
parent38891bacaef474e10b87356545b10d2d1ed8fb2d (diff)
[OpenMP] Implement omp_get_uid_from_device() / omp_get_device_from_uid() (#164392)
Use the implementation in libomptarget. If libomptarget is not available, always return the UID / device number of the host / the initial device.
Diffstat (limited to 'openmp')
-rw-r--r--openmp/device/include/DeviceTypes.h3
-rw-r--r--openmp/device/include/Interface.h4
-rw-r--r--openmp/device/src/State.cpp6
-rw-r--r--openmp/runtime/src/dllexports2
-rw-r--r--openmp/runtime/src/include/omp.h.var5
-rw-r--r--openmp/runtime/src/include/omp_lib.F90.var14
-rw-r--r--openmp/runtime/src/include/omp_lib.h.var19
-rw-r--r--openmp/runtime/src/kmp_ftn_entry.h29
-rw-r--r--openmp/runtime/src/kmp_ftn_os.h8
-rw-r--r--openmp/runtime/test/api/omp_device_uid.c77
10 files changed, 165 insertions, 2 deletions
diff --git a/openmp/device/include/DeviceTypes.h b/openmp/device/include/DeviceTypes.h
index 2e5d92380f04..213ccfe58b4f 100644
--- a/openmp/device/include/DeviceTypes.h
+++ b/openmp/device/include/DeviceTypes.h
@@ -21,6 +21,9 @@ template <typename T> using Constant = __gpu_constant T;
template <typename T> using Local = __gpu_local T;
template <typename T> using Global = __gpu_local T;
+// See definition in OpenMP (omp.h.var/omp_lib.(F90|h).var)
+#define omp_invalid_device -2
+
enum omp_proc_bind_t {
omp_proc_bind_false = 0,
omp_proc_bind_true = 1,
diff --git a/openmp/device/include/Interface.h b/openmp/device/include/Interface.h
index c4bfaaa2404b..71c3b1fc06d4 100644
--- a/openmp/device/include/Interface.h
+++ b/openmp/device/include/Interface.h
@@ -130,6 +130,10 @@ int omp_get_num_devices(void);
int omp_get_device_num(void);
+int omp_get_device_from_uid(const char *DeviceUid);
+
+const char *omp_get_uid_from_device(int DeviceNum);
+
int omp_get_num_teams(void);
int omp_get_team_num();
diff --git a/openmp/device/src/State.cpp b/openmp/device/src/State.cpp
index 9f38cf26f8c6..985e6b169137 100644
--- a/openmp/device/src/State.cpp
+++ b/openmp/device/src/State.cpp
@@ -403,6 +403,12 @@ int omp_get_num_devices(void) { return config::getNumDevices(); }
int omp_get_device_num(void) { return config::getDeviceNum(); }
+int omp_get_device_from_uid(const char *DeviceUid) {
+ return omp_invalid_device;
+}
+
+const char *omp_get_uid_from_device(int DeviceNum) { return nullptr; }
+
int omp_get_num_teams(void) { return mapping::getNumberOfBlocksInKernel(); }
int omp_get_team_num() { return mapping::getBlockIdInKernel(); }
diff --git a/openmp/runtime/src/dllexports b/openmp/runtime/src/dllexports
index 3983dae80c9f..00becd1a657f 100644
--- a/openmp/runtime/src/dllexports
+++ b/openmp/runtime/src/dllexports
@@ -544,6 +544,8 @@ kmp_set_disp_num_buffers 890
omp_get_devices_all_allocator 819
omp_get_memspace_num_resources 820
omp_get_submemspace 821
+ omp_get_device_from_uid 822
+ omp_get_uid_from_device 823
%ifndef stub
__kmpc_set_default_allocator
__kmpc_get_default_allocator
diff --git a/openmp/runtime/src/include/omp.h.var b/openmp/runtime/src/include/omp.h.var
index 74f385feb3ea..e98df731ad88 100644
--- a/openmp/runtime/src/include/omp.h.var
+++ b/openmp/runtime/src/include/omp.h.var
@@ -536,6 +536,11 @@
/* OpenMP 5.2 */
extern int __KAI_KMPC_CONVENTION omp_in_explicit_task(void);
+ #define omp_invalid_device -2
+
+ /* OpenMP 6.0 */
+ extern int __KAI_KMPC_CONVENTION omp_get_device_from_uid(const char *DeviceUid);
+ extern const char * __KAI_KMPC_CONVENTION omp_get_uid_from_device(int DeviceNum);
/* LLVM Extensions */
extern void *llvm_omp_target_dynamic_shared_alloc(void);
diff --git a/openmp/runtime/src/include/omp_lib.F90.var b/openmp/runtime/src/include/omp_lib.F90.var
index 90d7e49ebf54..159b42ab5b5c 100644
--- a/openmp/runtime/src/include/omp_lib.F90.var
+++ b/openmp/runtime/src/include/omp_lib.F90.var
@@ -215,6 +215,8 @@
integer (kind=omp_interop_kind), parameter, public :: omp_interop_none = 0
+ integer (kind=omp_integer_kind), parameter, public :: omp_invalid_device = -2
+
interface
! ***
@@ -417,6 +419,18 @@
integer (kind=omp_integer_kind) omp_get_device_num
end function omp_get_device_num
+ function omp_get_uid_from_device(device_num) bind(c)
+ use omp_lib_kinds
+ integer (kind=omp_integer_kind), value :: device_num
+ character (len=*) omp_get_uid_from_device
+ end function omp_get_uid_from_device
+
+ function omp_get_device_from_uid(device_uid) bind(c)
+ use omp_lib_kinds
+ character (len=*), value :: device_uid
+ integer (kind=omp_integer_kind) omp_get_device_from_uid
+ end function omp_get_device_from_uid
+
function omp_pause_resource(kind, device_num) bind(c)
use omp_lib_kinds
integer (kind=omp_pause_resource_kind), value :: kind
diff --git a/openmp/runtime/src/include/omp_lib.h.var b/openmp/runtime/src/include/omp_lib.h.var
index a50bb018c7cc..468eb03e99ef 100644
--- a/openmp/runtime/src/include/omp_lib.h.var
+++ b/openmp/runtime/src/include/omp_lib.h.var
@@ -291,6 +291,9 @@
integer(kind=omp_interop_kind)omp_interop_none
parameter(omp_interop_none=0)
+ integer(kind=omp_integer_kind)omp_invalid_device
+ parameter(omp_invalid_device=-2)
+
interface
! ***
@@ -486,6 +489,18 @@
integer (kind=omp_integer_kind) omp_get_device_num
end function omp_get_device_num
+ function omp_get_uid_from_device(device_num) bind(c)
+ import
+ integer (kind=omp_integer_kind), value :: device_num
+ character (len=*) omp_get_uid_from_device
+ end function omp_get_uid_from_device
+
+ function omp_get_device_from_uid(device_uid) bind(c)
+ import
+ character (len=*), value :: device_uid
+ integer (kind=omp_integer_kind) omp_get_device_from_uid
+ end function omp_get_device_from_uid
+
function omp_pause_resource(kind, device_num) bind(c)
import
integer (kind=omp_pause_resource_kind), value :: kind
@@ -1159,6 +1174,8 @@
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_initial_device
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_num_devices
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_device_num
+!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_uid_from_device
+!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_device_from_uid
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_pause_resource
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_pause_resource_all
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_supported_active_levels
@@ -1242,6 +1259,8 @@
!$omp declare target(omp_get_initial_device )
!$omp declare target(omp_get_num_devices )
!$omp declare target(omp_get_device_num )
+!$omp declare target(omp_get_uid_from_device )
+!$omp declare target(omp_get_device_from_uid )
!$omp declare target(omp_pause_resource )
!$omp declare target(omp_pause_resource_all )
!$omp declare target(omp_get_supported_active_levels )
diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h
index 2b0063eb23a0..49c56d2b9a76 100644
--- a/openmp/runtime/src/kmp_ftn_entry.h
+++ b/openmp/runtime/src/kmp_ftn_entry.h
@@ -1543,13 +1543,38 @@ int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)(void) {
#endif
}
-// This function will be defined in libomptarget. When libomptarget is not
-// loaded, we assume we are on the host and return KMP_HOST_DEVICE.
+// These functions will be defined in libomptarget. When libomptarget is not
+// loaded, we assume we are on the host.
// 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 KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)();
}
+const char *FTN_STDCALL FTN_GET_UID_FROM_DEVICE(int device_num)
+ KMP_WEAK_ATTRIBUTE_EXTERNAL;
+const char *FTN_STDCALL FTN_GET_UID_FROM_DEVICE(int device_num) {
+#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
+ return nullptr;
+#else
+ const char *(*fptr)(int);
+ if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_uid_from_device")))
+ return (*fptr)(device_num);
+ // Returns the same string as used by libomptarget
+ return "HOST";
+#endif
+}
+int FTN_STDCALL FTN_GET_DEVICE_FROM_UID(const char *device_uid)
+ KMP_WEAK_ATTRIBUTE_EXTERNAL;
+int FTN_STDCALL FTN_GET_DEVICE_FROM_UID(const char *device_uid) {
+#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
+ return omp_invalid_device;
+#else
+ int (*fptr)(const char *);
+ if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_device_from_uid")))
+ return (*fptr)(device_uid);
+ return KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)();
+#endif
+}
// Compiler will ensure that this is only called from host in sequential region
int FTN_STDCALL KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE)(kmp_pause_status_t kind,
diff --git a/openmp/runtime/src/kmp_ftn_os.h b/openmp/runtime/src/kmp_ftn_os.h
index ae0ed067235e..c439a058f22b 100644
--- a/openmp/runtime/src/kmp_ftn_os.h
+++ b/openmp/runtime/src/kmp_ftn_os.h
@@ -140,6 +140,8 @@
#define FTN_GET_MEMSPACE_NUM_RESOURCES omp_get_memspace_num_resources
#define FTN_GET_SUBMEMSPACE omp_get_submemspace
#define FTN_GET_DEVICE_NUM omp_get_device_num
+#define FTN_GET_UID_FROM_DEVICE omp_get_uid_from_device
+#define FTN_GET_DEVICE_FROM_UID omp_get_device_from_uid
#define FTN_SET_AFFINITY_FORMAT omp_set_affinity_format
#define FTN_GET_AFFINITY_FORMAT omp_get_affinity_format
#define FTN_DISPLAY_AFFINITY omp_display_affinity
@@ -289,6 +291,8 @@
#define FTN_ALLOC omp_alloc_
#define FTN_FREE omp_free_
#define FTN_GET_DEVICE_NUM omp_get_device_num_
+#define FTN_GET_UID_FROM_DEVICE omp_get_uid_from_device_
+#define FTN_GET_DEVICE_FROM_UID omp_get_device_from_uid_
#define FTN_SET_AFFINITY_FORMAT omp_set_affinity_format_
#define FTN_GET_AFFINITY_FORMAT omp_get_affinity_format_
#define FTN_DISPLAY_AFFINITY omp_display_affinity_
@@ -436,6 +440,8 @@
#define FTN_GET_MEMSPACE_NUM_RESOURCES OMP_GET_MEMSPACE_NUM_RESOURCES
#define FTN_GET_SUBMEMSPACE OMP_GET_SUBMEMSPACE
#define FTN_GET_DEVICE_NUM OMP_GET_DEVICE_NUM
+#define FTN_GET_UID_FROM_DEVICE OMP_GET_UID_FROM_DEVICE
+#define FTN_GET_DEVICE_FROM_UID OMP_GET_DEVICE_FROM_UID
#define FTN_SET_AFFINITY_FORMAT OMP_SET_AFFINITY_FORMAT
#define FTN_GET_AFFINITY_FORMAT OMP_GET_AFFINITY_FORMAT
#define FTN_DISPLAY_AFFINITY OMP_DISPLAY_AFFINITY
@@ -585,6 +591,8 @@
#define FTN_ALLOC OMP_ALLOC_
#define FTN_FREE OMP_FREE_
#define FTN_GET_DEVICE_NUM OMP_GET_DEVICE_NUM_
+#define FTN_GET_UID_FROM_DEVICE OMP_GET_UID_FROM_DEVICE_
+#define FTN_GET_DEVICE_FROM_UID OMP_GET_DEVICE_FROM_UID_
#define FTN_SET_AFFINITY_FORMAT OMP_SET_AFFINITY_FORMAT_
#define FTN_GET_AFFINITY_FORMAT OMP_GET_AFFINITY_FORMAT_
#define FTN_DISPLAY_AFFINITY OMP_DISPLAY_AFFINITY_
diff --git a/openmp/runtime/test/api/omp_device_uid.c b/openmp/runtime/test/api/omp_device_uid.c
new file mode 100644
index 000000000000..40a1cbb644c7
--- /dev/null
+++ b/openmp/runtime/test/api/omp_device_uid.c
@@ -0,0 +1,77 @@
+// RUN: %libomp-compile-and-run 2>&1 | FileCheck %s
+// Linking fails for icc 18
+// UNSUPPORTED: icc-18
+
+#include <omp_testsuite.h>
+#include <string.h>
+
+int test_omp_device_uid(int device_num) {
+ const char *device_uid = omp_get_uid_from_device(device_num);
+ if (device_uid == NULL) {
+ printf("FAIL for device %d: omp_get_uid_from_device returned NULL\n",
+ device_num);
+ return 0;
+ }
+
+ int device_num_from_uid = omp_get_device_from_uid(device_uid);
+ if (device_num_from_uid != device_num) {
+ printf(
+ "FAIL for device %d: omp_get_device_from_uid returned %d (UID: %s)\n",
+ device_num, device_num_from_uid, device_uid);
+ return 0;
+ }
+
+ if (device_num == omp_get_initial_device())
+ return 1;
+
+ int success = 1;
+
+// Note that the following code may be executed on the host if the host is the
+// device
+#pragma omp target map(tofrom : success) device(device_num)
+ {
+ int device_num = omp_get_device_num();
+
+ // omp_get_uid_from_device() in the device runtime is a dummy function
+ // returning NULL
+ const char *device_uid = omp_get_uid_from_device(device_num);
+
+ // omp_get_device_from_uid() in the device runtime is a dummy function
+ // returning omp_invalid_device.
+ int device_num_from_uid = omp_get_device_from_uid(device_uid);
+
+ // Depending on whether we're executing on the device or the host, we either
+ // got NULL as the device UID or the correct device UID. Consequently,
+ // omp_get_device_from_uid() either returned omp_invalid_device or the
+ // correct device number (aka omp_get_initial_device()).
+ if (device_uid ? device_num_from_uid != device_num
+ : device_num_from_uid != omp_invalid_device) {
+ printf("FAIL for device %d (target): omp_get_device_from_uid returned %d "
+ "(UID: %s)\n",
+ device_num, device_num_from_uid, device_uid);
+ success = 0;
+ }
+ }
+
+ return success;
+}
+
+int main() {
+ int num_devices = omp_get_num_devices();
+ int num_failed = 0;
+ // (also test initial device aka num_devices)
+ for (int i = 0; i < num_devices + 1; i++) {
+ if (!test_omp_device_uid(i)) {
+ printf("FAIL for device %d\n", i);
+ num_failed++;
+ }
+ }
+ if (num_failed) {
+ printf("FAIL\n");
+ return 1;
+ }
+ printf("PASS\n");
+ return 0;
+}
+
+// CHECK: PASS