https://gcc.gnu.org/g:e2464868d9931e4820cb2a94c9a1cc2fd93a3f24
commit e2464868d9931e4820cb2a94c9a1cc2fd93a3f24 Author: Tobias Burnus <tbur...@baylibre.com> Date: Thu Jan 23 22:37:06 2025 +0100 OpenMP: Fix omp_get_device_from_uid, minor cleanup In Fortran, omp_get_device_from_uid can also accept substrings, which are then not NUL terminated. Fixed by introducing a fortran.c wrapper function. Additionally, in case of a fail the plugin functions now return NULL instead of failing fatally such that a fall-back UID is generated. gcc/ChangeLog: * omp-general.cc (omp_runtime_api_procname): Strip "omp_" from string; move get_device_from_uid as now a '_' suffix exists. libgomp/ChangeLog: * fortran.c (omp_get_device_from_uid_): New function. * libgomp.map (GOMP_6.0): Add it. * oacc-host.c (host_dispatch): Init '.uid' and '.get_uid_func'. * omp_lib.f90.in: Make it used by removing bind(C). * omp_lib.h.in: Likewise. * target.c (omp_get_device_from_uid): Ensure the device is initialized. * plugin/plugin-gcn.c (GOMP_OFFLOAD_get_uid): Add function comment; return NULL in case of an error. * plugin/plugin-nvptx.c (GOMP_OFFLOAD_get_uid): Likewise. * testsuite/libgomp.fortran/device_uid.f90: Update to test substrings. (cherry picked from commit cdb9aa0f623ec7899da445a47f4a502b2987dc7b) Diff: --- gcc/ChangeLog.omp | 8 ++++++++ gcc/omp-general.cc | 4 ++-- libgomp/ChangeLog.omp | 16 ++++++++++++++++ libgomp/fortran.c | 18 ++++++++++++++++++ libgomp/libgomp.map | 1 + libgomp/oacc-host.c | 2 ++ libgomp/omp_lib.f90.in | 5 ++--- libgomp/omp_lib.h.in | 5 ++--- libgomp/plugin/plugin-gcn.c | 8 +++++++- libgomp/plugin/plugin-nvptx.c | 7 +++++-- libgomp/target.c | 7 +++++-- libgomp/testsuite/libgomp.fortran/device_uid.f90 | 18 ++++++++++++++++-- 12 files changed, 84 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index 070724a43a10..31f2140cdd97 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,3 +1,11 @@ +2025-01-23 Tobias Burnus <tbur...@baylibre.com> + + Backported from master: + 2024-09-23 Tobias Burnus <tbur...@baylibre.com> + + * omp-general.cc (omp_runtime_api_procname): Strip "omp_" from + string; move get_device_from_uid as now a '_' suffix exists. + 2025-01-23 Tobias Burnus <tbur...@baylibre.com> Backported from master: diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc index 7437337063a0..bd9c2894b0ba 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -3431,7 +3431,6 @@ omp_runtime_api_procname (const char *name) "alloc", "calloc", "free", - "get_device_from_uid", "get_interop_int", "get_interop_ptr", "get_mapped_ptr", @@ -3461,6 +3460,7 @@ omp_runtime_api_procname (const char *name) "get_cancellation", "get_default_allocator", "get_default_device", + "get_device_from_uid", "get_device_num", "get_dynamic", "get_initial_device", @@ -3510,7 +3510,7 @@ omp_runtime_api_procname (const char *name) as DECL_NAME only omp_* and omp_*_8 appear. */ "display_env", "get_ancestor_thread_num", - "omp_get_uid_from_device", + "get_uid_from_device", "get_partition_place_nums", "get_place_num_procs", "get_place_proc_ids", diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp index a56968070e02..a6c57e43d5c0 100644 --- a/libgomp/ChangeLog.omp +++ b/libgomp/ChangeLog.omp @@ -1,3 +1,19 @@ +2025-01-23 Tobias Burnus <tbur...@baylibre.com> + + Backported from master: + 2024-09-23 Tobias Burnus <tbur...@baylibre.com> + + * fortran.c (omp_get_device_from_uid_): New function. + * libgomp.map (GOMP_6.0): Add it. + * oacc-host.c (host_dispatch): Init '.uid' and '.get_uid_func'. + * omp_lib.f90.in: Make it used by removing bind(C). + * omp_lib.h.in: Likewise. + * target.c (omp_get_device_from_uid): Ensure the device is initialized. + * plugin/plugin-gcn.c (GOMP_OFFLOAD_get_uid): Add function comment; + return NULL in case of an error. + * plugin/plugin-nvptx.c (GOMP_OFFLOAD_get_uid): Likewise. + * testsuite/libgomp.fortran/device_uid.f90: Update to test substrings. + 2025-01-23 Tobias Burnus <tbur...@baylibre.com> Backported from master: diff --git a/libgomp/fortran.c b/libgomp/fortran.c index 9b7f093555b0..7976e5b9638d 100644 --- a/libgomp/fortran.c +++ b/libgomp/fortran.c @@ -834,6 +834,24 @@ omp_get_interop_rc_desc_ (const char **res, size_t *res_len, *res_len = *res ? strlen (*res) : 0; } +int +omp_get_device_from_uid_ (const char *uid, size_t uid_len) +{ +#ifndef LIBGOMP_OFFLOADED_ONLY + char *str = __builtin_alloca ((uid_len + 1) * sizeof (char)); + memcpy (str, uid, uid_len * sizeof (char)); + str[uid_len] = '\0'; + return omp_get_device_from_uid (str); +#else + /* Inside the target region, invoking this routine is undefined + behavior; thus, resolve it already here - instead of inside + libgomp/config/.../target.c. + Note that on nvptx __builtin_alloca is defined, but fails with a sorry + during compilation, as it is unsupported until isa 7.3 / sm_52. */ + return omp_invalid_device; +#endif +} + void omp_get_uid_from_device_ (const char **res, size_t *res_len, int32_t device_num) diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map index b32334c18cc9..d40f8eb6eddb 100644 --- a/libgomp/libgomp.map +++ b/libgomp/libgomp.map @@ -448,6 +448,7 @@ GOMP_5.1.3 { GOMP_6.0 { global: omp_get_device_from_uid; + omp_get_device_from_uid_; omp_get_uid_from_device; omp_get_uid_from_device_; omp_get_uid_from_device_8_; diff --git a/libgomp/oacc-host.c b/libgomp/oacc-host.c index b6883850250d..f523e47a6654 100644 --- a/libgomp/oacc-host.c +++ b/libgomp/oacc-host.c @@ -273,6 +273,7 @@ host_openacc_destroy_thread_data (void *tls_data __attribute__ ((unused))) static struct gomp_device_descr host_dispatch = { .name = "host", + .uid = NULL, .capabilities = (GOMP_OFFLOAD_CAP_SHARED_MEM | GOMP_OFFLOAD_CAP_NATIVE_EXEC | GOMP_OFFLOAD_CAP_OPENACC_200), @@ -280,6 +281,7 @@ static struct gomp_device_descr host_dispatch = .type = OFFLOAD_TARGET_TYPE_HOST, .get_name_func = host_get_name, + .get_uid_func = NULL, .get_caps_func = host_get_caps, .get_type_func = host_get_type, .get_num_devices_func = host_get_num_devices, diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in index 40df7d2116a5..edfaa915b4cf 100644 --- a/libgomp/omp_lib.f90.in +++ b/libgomp/omp_lib.f90.in @@ -1004,10 +1004,9 @@ end interface interface - ! Note: In gfortran, strings are \0 termined - integer(c_int) function omp_get_device_from_uid(uid) bind(C) + integer(c_int) function omp_get_device_from_uid (uid) use iso_c_binding - character(c_char), intent(in) :: uid(*) + character, intent(in) :: uid(*) end function omp_get_device_from_uid end interface diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in index 450ae8b854fc..05ce89254299 100644 --- a/libgomp/omp_lib.h.in +++ b/libgomp/omp_lib.h.in @@ -610,10 +610,9 @@ end interface interface -! Note: In gfortran, strings are \0 termined - integer(c_int) function omp_get_device_from_uid(uid) bind(C) + integer(c_int) function omp_get_device_from_uid (uid) use iso_c_binding - character(c_char), intent(in) :: uid(*) + character, intent(in) :: uid(*) end function omp_get_device_from_uid end interface diff --git a/libgomp/plugin/plugin-gcn.c b/libgomp/plugin/plugin-gcn.c index 7fcd7fa4274e..e59fdb24a24b 100644 --- a/libgomp/plugin/plugin-gcn.c +++ b/libgomp/plugin/plugin-gcn.c @@ -3318,6 +3318,9 @@ GOMP_OFFLOAD_get_name (void) return "gcn"; } +/* Return the UID; if not available return NULL. + Returns freshly allocated memoy. */ + const char * GOMP_OFFLOAD_get_uid (int ord) { @@ -3330,7 +3333,10 @@ GOMP_OFFLOAD_get_uid (int ord) status = hsa_fns.hsa_agent_get_info_fn (agent->id, HSA_AMD_AGENT_INFO_UUID, str); if (status != HSA_STATUS_SUCCESS) - hsa_fatal ("Could not obtain device UUID", status); + { + free (str); + return NULL; + } return str; } diff --git a/libgomp/plugin/plugin-nvptx.c b/libgomp/plugin/plugin-nvptx.c index b00509b6be25..a4f338cb50a7 100644 --- a/libgomp/plugin/plugin-nvptx.c +++ b/libgomp/plugin/plugin-nvptx.c @@ -1253,6 +1253,9 @@ GOMP_OFFLOAD_get_name (void) return "nvptx"; } +/* Return the UID; if not available return NULL. + Returns freshly allocated memoy. */ + const char * GOMP_OFFLOAD_get_uid (int ord) { @@ -1265,9 +1268,9 @@ GOMP_OFFLOAD_get_uid (int ord) else if (CUDA_CALL_EXISTS (cuDeviceGetUuid)) r = CUDA_CALL_NOCHECK (cuDeviceGetUuid, &s, dev->dev); else - r = CUDA_ERROR_NOT_FOUND; + return NULL; if (r != CUDA_SUCCESS) - GOMP_PLUGIN_fatal ("cuDeviceGetUuid error: %s", cuda_error (r)); + NULL; size_t len = strlen ("GPU-12345678-9abc-defg-hijk-lmniopqrstuv"); char *str = (char *) GOMP_PLUGIN_malloc (len + 1); diff --git a/libgomp/target.c b/libgomp/target.c index ca05398741e6..c9bf120ce43c 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -5865,8 +5865,11 @@ omp_get_device_from_uid (const char *uid) if (strcmp (uid, str_omp_initial_device) == 0) return omp_initial_device; for (int dev = 0; dev < gomp_get_num_devices (); dev++) - if (strcmp (uid, gomp_get_uid_for_device (&devices[dev], dev)) == 0) - return dev; + { + struct gomp_device_descr *devicep = resolve_device (dev, false); + if (strcmp (uid, gomp_get_uid_for_device (devicep, dev)) == 0) + return dev; + } return omp_invalid_device; } diff --git a/libgomp/testsuite/libgomp.fortran/device_uid.f90 b/libgomp/testsuite/libgomp.fortran/device_uid.f90 index 4c2a28a104e2..504f6caaf07d 100644 --- a/libgomp/testsuite/libgomp.fortran/device_uid.f90 +++ b/libgomp/testsuite/libgomp.fortran/device_uid.f90 @@ -12,7 +12,7 @@ program main do i = omp_invalid_device - 1, omp_get_num_devices () + 1 str => omp_get_uid_from_device (i) - dev = omp_get_device_from_uid (str); + dev = omp_get_device_from_uid (str) ! print *, i, str, dev if (i < omp_initial_device .or. i > omp_get_num_devices ()) then if (dev /= omp_invalid_device .or. associated(str)) & @@ -30,12 +30,26 @@ program main stop 4 end if strs(dev)%str => str + + block + ! Check substring handling + character(len=100) :: long_str + integer :: dev2 + long_str = str // "ABCDEF" + dev2 = omp_get_device_from_uid (long_str(1:len(str))) + if (i == omp_initial_device .or. i == omp_get_num_devices ()) then + if (dev2 /= omp_initial_device .and. dev2 /= omp_get_num_devices ()) & + stop 5 + else if (dev /= dev2) then + stop 6 + end if + end block end do do i = 0, omp_get_num_devices () - 1 do j = i + 1, omp_get_num_devices () if (strs(i)%str == strs(j)%str) & - stop 4 + stop 7 end do end do deallocate (strs)