[Openmp-commits] [openmp] [OpenMP] Add Fortran support routines for dyn_groupprivate (OpenMP 6.1) (PR #211630)
Michael Klemm via Openmp-commits
openmp-commits at lists.llvm.org
Wed Sep 30 10:54:50 PDT 2026
https://github.com/mjklemm updated https://github.com/llvm/llvm-project/pull/211630
>From ed57d5421ad8ab73f89cbcf498be076dbd612bf3 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 23 Jul 2026 15:28:59 +0200
Subject: [PATCH 1/5] [OpenMP] Add Fortran routine declarations for device
dynamic memory
---
openmp/module/omp_lib.F90.var | 48 +++++++++++++++++++++++++++++++++++
openmp/module/omp_lib.h.var | 45 ++++++++++++++++++++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/openmp/module/omp_lib.F90.var b/openmp/module/omp_lib.F90.var
index a41b2faad9d3d..0b04190e2e6b7 100644
--- a/openmp/module/omp_lib.F90.var
+++ b/openmp/module/omp_lib.F90.var
@@ -36,6 +36,7 @@
integer, parameter, public :: omp_control_tool_result_kind = omp_integer_kind
integer, parameter, public :: omp_allocator_handle_kind = c_intptr_t
integer, parameter, public :: omp_memspace_handle_kind = c_intptr_t
+ integer, parameter, public :: omp_access_kind = omp_integer_kind
integer, parameter, public :: omp_alloctrait_key_kind = omp_integer_kind
integer, parameter, public :: omp_alloctrait_val_kind = c_intptr_t
integer, parameter, public :: omp_interop_kind = c_intptr_t
@@ -82,6 +83,7 @@
public :: omp_control_tool_result_kind
public :: omp_allocator_handle_kind
public :: omp_memspace_handle_kind
+ public :: omp_access_kind
public :: omp_alloctrait_key_kind
public :: omp_alloctrait_val_kind
public :: omp_interop_kind
@@ -207,6 +209,9 @@
integer (kind=omp_memspace_handle_kind), parameter, public :: llvm_omp_target_shared_mem_space = 101
integer (kind=omp_memspace_handle_kind), parameter, public :: llvm_omp_target_device_mem_space = 102
+ integer (kind=omp_access_kind), parameter, public :: omp_access_cgroup = 0
+ integer (kind=omp_access_kind), parameter, public :: omp_access_pteam = 1
+
integer (kind=omp_pause_resource_kind), parameter, public :: omp_pause_resume = 0
integer (kind=omp_pause_resource_kind), parameter, public :: omp_pause_soft = 1
integer (kind=omp_pause_resource_kind), parameter, public :: omp_pause_hard = 2
@@ -933,6 +938,44 @@
integer, intent(in) :: resources(*)
end function omp_get_submemspace
+ function omp_get_dyn_gprivate_ptr(offset, access_group)
+ use omp_lib_kinds
+ use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t
+ type (c_ptr) omp_get_dyn_gprivate_ptr
+ integer (kind=c_size_t), value, optional :: offset
+ integer (kind=omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_ptr
+
+ function omp_get_dyn_gprivate_nofb_ptr(offset, access_group)
+ use omp_lib_kinds
+ use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t
+ type (c_ptr) omp_get_dyn_gprivate_nofb_ptr
+ integer (kind=c_size_t), value, optional :: offset
+ integer (kind=omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_nofb_ptr
+
+ function omp_get_dyn_gprivate_size(access_group)
+ use omp_lib_kinds
+ use, intrinsic :: iso_c_binding, only : c_size_t
+ integer (kind=c_size_t) omp_get_dyn_gprivate_size
+ integer (kind=omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_size
+
+ function omp_get_dyn_gprivate_memspace(access_group)
+ use omp_lib_kinds
+ integer (kind=omp_memspace_handle_kind) &
+ omp_get_dyn_gprivate_memspace
+ integer (kind=omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_memspace
+
+ function omp_get_gprivate_limit(device_num, access_group)
+ use omp_lib_kinds
+ use, intrinsic :: iso_c_binding, only : c_size_t, c_int
+ integer (kind=c_size_t) omp_get_gprivate_limit
+ integer (kind=c_int), value :: device_num
+ integer (kind=omp_access_kind), value, optional :: access_group
+ end function omp_get_gprivate_limit
+
! ***
! *** kmp_* entry points
! ***
@@ -1269,6 +1312,11 @@
public :: kmp_set_warnings_on
public :: kmp_set_warnings_off
public :: kmp_get_cancellation_status
+ public :: omp_get_dyn_gprivate_ptr
+ public :: omp_get_dyn_gprivate_nofb_ptr
+ public :: omp_get_dyn_gprivate_size
+ public :: omp_get_dyn_gprivate_memspace
+ public :: omp_get_gprivate_limit
public :: omp_get_num_interop_properties
public :: omp_get_interop_int
public :: omp_get_interop_ptr
diff --git a/openmp/module/omp_lib.h.var b/openmp/module/omp_lib.h.var
index 5e1996e31fe0a..de00b05cb2cf1 100644
--- a/openmp/module/omp_lib.h.var
+++ b/openmp/module/omp_lib.h.var
@@ -42,6 +42,8 @@
parameter(omp_allocator_handle_kind=int_ptr_kind())
integer omp_memspace_handle_kind
parameter(omp_memspace_handle_kind=int_ptr_kind())
+ integer omp_access_kind
+ parameter(omp_access_kind=omp_integer_kind)
integer omp_alloctrait_key_kind
parameter(omp_alloctrait_key_kind=omp_integer_kind)
integer omp_alloctrait_val_kind
@@ -273,6 +275,11 @@
integer(omp_memspace_handle_kind)llvm_omp_target_device_mem_space
parameter(llvm_omp_target_device_mem_space=102)
+ integer(kind=omp_access_kind)omp_access_cgroup
+ parameter(omp_access_cgroup=0)
+ integer(kind=omp_access_kind)omp_access_pteam
+ parameter(omp_access_pteam=1)
+
integer(kind=omp_pause_resource_kind)omp_pause_resume
parameter(omp_pause_resume=0)
integer(kind=omp_pause_resource_kind)omp_pause_soft
@@ -1025,6 +1032,44 @@
integer, intent(in) :: resources(*)
end function omp_get_submemspace
+ function omp_get_dyn_gprivate_ptr(offset, access_group)
+ use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t
+ import
+ type (c_ptr) omp_get_dyn_gprivate_ptr
+ integer (kind=c_size_t), value, optional :: offset
+ integer(omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_ptr
+
+ function omp_get_dyn_gprivate_nofb_ptr(offset, access_group)
+ use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t
+ import
+ type (c_ptr) omp_get_dyn_gprivate_nofb_ptr
+ integer (kind=c_size_t), value, optional :: offset
+ integer(omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_nofb_ptr
+
+ function omp_get_dyn_gprivate_size(access_group)
+ use, intrinsic :: iso_c_binding, only : c_size_t
+ import
+ integer (kind=c_size_t) omp_get_dyn_gprivate_size
+ integer(omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_size
+
+ function omp_get_dyn_gprivate_memspace(access_group)
+ import
+ integer(omp_memspace_handle_kind)
+ & omp_get_dyn_gprivate_memspace
+ integer(omp_access_kind), value, optional :: access_group
+ end function omp_get_dyn_gprivate_memspace
+
+ function omp_get_gprivate_limit(device_num, access_group)
+ use, intrinsic :: iso_c_binding, only : c_size_t, c_int
+ import
+ integer (kind=c_size_t) omp_get_gprivate_limit
+ integer (kind=c_int), value :: device_num
+ integer(omp_access_kind), value, optional :: access_group
+ end function omp_get_gprivate_limit
+
! ***
! *** kmp_* entry points
>From 9987ed0891e09cfac539ac70b0555feab65f8e8a Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 23 Jul 2026 17:34:57 +0200
Subject: [PATCH 2/5] Add stub implementation
---
openmp/runtime/src/kmp.h | 5 +++++
openmp/runtime/src/kmp_ftn_entry.h | 24 ++++++++++++++++++++++++
openmp/runtime/src/kmp_ftn_os.h | 20 ++++++++++++++++++++
3 files changed, 49 insertions(+)
diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h
index 818e07c2bb23f..32c22177e7b05 100644
--- a/openmp/runtime/src/kmp.h
+++ b/openmp/runtime/src/kmp.h
@@ -1086,6 +1086,11 @@ extern omp_allocator_handle_t const llvm_omp_target_device_mem_alloc;
extern omp_allocator_handle_t const kmp_max_mem_alloc;
extern omp_allocator_handle_t __kmp_def_allocator;
+typedef enum omp_access_t {
+ omp_access_cgroup = 0,
+ omp_access_pteam = 1
+} omp_access_t;
+
// end of duplicate type definitions from omp.h
#endif
diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h
index 1c8e568b78407..eebd08502728a 100644
--- a/openmp/runtime/src/kmp_ftn_entry.h
+++ b/openmp/runtime/src/kmp_ftn_entry.h
@@ -551,6 +551,30 @@ FTN_GET_SUBMEMSPACE(omp_memspace_handle_t KMP_DEREF memspace,
#endif
}
+// The C (KMP_FTN_PLAIN) versions of the dynamic groupprivate information
+// routines are defined in kmp_csupport.cpp, so only the Fortran entry points
+// are generated here. The offset and access_group arguments are optional in
+// Fortran and are passed as null pointers when omitted. These stubs report that
+// no dynamic groupprivate block exists.
+#if KMP_FTN_ENTRIES != KMP_FTN_PLAIN
+void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_PTR(size_t *, omp_access_t *) {
+ return NULL;
+}
+
+void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_NOFB_PTR(size_t *, omp_access_t *) {
+ return NULL;
+}
+
+size_t FTN_STDCALL FTN_GET_DYN_GPRIVATE_SIZE(omp_access_t *) { return 0; }
+
+omp_memspace_handle_t FTN_STDCALL
+FTN_GET_DYN_GPRIVATE_MEMSPACE(omp_access_t *) {
+ return omp_null_mem_space;
+}
+
+size_t FTN_STDCALL FTN_GET_GPRIVATE_LIMIT(int *, omp_access_t *) { return 0; }
+#endif // KMP_FTN_ENTRIES != KMP_FTN_PLAIN
+
/* OpenMP 5.0 affinity format support */
#ifndef KMP_STUB
static void __kmp_fortran_strncpy_truncate(char *buffer, size_t buf_size,
diff --git a/openmp/runtime/src/kmp_ftn_os.h b/openmp/runtime/src/kmp_ftn_os.h
index c439a058f22b4..1e981b44031fb 100644
--- a/openmp/runtime/src/kmp_ftn_os.h
+++ b/openmp/runtime/src/kmp_ftn_os.h
@@ -139,6 +139,11 @@
#define FTN_GET_DEVICES_ALL_ALLOCATOR omp_get_devices_all_allocator
#define FTN_GET_MEMSPACE_NUM_RESOURCES omp_get_memspace_num_resources
#define FTN_GET_SUBMEMSPACE omp_get_submemspace
+#define FTN_GET_DYN_GPRIVATE_PTR omp_get_dyn_gprivate_ptr
+#define FTN_GET_DYN_GPRIVATE_NOFB_PTR omp_get_dyn_gprivate_nofb_ptr
+#define FTN_GET_DYN_GPRIVATE_SIZE omp_get_dyn_gprivate_size
+#define FTN_GET_DYN_GPRIVATE_MEMSPACE omp_get_dyn_gprivate_memspace
+#define FTN_GET_GPRIVATE_LIMIT omp_get_gprivate_limit
#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
@@ -288,6 +293,11 @@
#define FTN_GET_DEVICES_ALL_ALLOCATOR omp_get_devices_all_allocator_
#define FTN_GET_MEMSPACE_NUM_RESOURCES omp_get_memspace_num_resources_
#define FTN_GET_SUBMEMSPACE omp_get_submemspace_
+#define FTN_GET_DYN_GPRIVATE_PTR omp_get_dyn_gprivate_ptr_
+#define FTN_GET_DYN_GPRIVATE_NOFB_PTR omp_get_dyn_gprivate_nofb_ptr_
+#define FTN_GET_DYN_GPRIVATE_SIZE omp_get_dyn_gprivate_size_
+#define FTN_GET_DYN_GPRIVATE_MEMSPACE omp_get_dyn_gprivate_memspace_
+#define FTN_GET_GPRIVATE_LIMIT omp_get_gprivate_limit_
#define FTN_ALLOC omp_alloc_
#define FTN_FREE omp_free_
#define FTN_GET_DEVICE_NUM omp_get_device_num_
@@ -439,6 +449,11 @@
#define FTN_GET_DEVICES_ALL_ALLOCATOR OMP_GET_DEVICES_ALL_ALLOCATOR
#define FTN_GET_MEMSPACE_NUM_RESOURCES OMP_GET_MEMSPACE_NUM_RESOURCES
#define FTN_GET_SUBMEMSPACE OMP_GET_SUBMEMSPACE
+#define FTN_GET_DYN_GPRIVATE_PTR OMP_GET_DYN_GPRIVATE_PTR
+#define FTN_GET_DYN_GPRIVATE_NOFB_PTR OMP_GET_DYN_GPRIVATE_NOFB_PTR
+#define FTN_GET_DYN_GPRIVATE_SIZE OMP_GET_DYN_GPRIVATE_SIZE
+#define FTN_GET_DYN_GPRIVATE_MEMSPACE OMP_GET_DYN_GPRIVATE_MEMSPACE
+#define FTN_GET_GPRIVATE_LIMIT OMP_GET_GPRIVATE_LIMIT
#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
@@ -588,6 +603,11 @@
#define FTN_GET_DEVICES_ALL_ALLOCATOR OMP_GET_DEVICES_ALL_ALLOCATOR_
#define FTN_GET_MEMSPACE_NUM_RESOURCES OMP_GET_MEMSPACE_NUM_RESOURCES_
#define FTN_GET_SUBMEMSPACE OMP_GET_SUBMEMSPACE_
+#define FTN_GET_DYN_GPRIVATE_PTR OMP_GET_DYN_GPRIVATE_PTR_
+#define FTN_GET_DYN_GPRIVATE_NOFB_PTR OMP_GET_DYN_GPRIVATE_NOFB_PTR_
+#define FTN_GET_DYN_GPRIVATE_SIZE OMP_GET_DYN_GPRIVATE_SIZE_
+#define FTN_GET_DYN_GPRIVATE_MEMSPACE OMP_GET_DYN_GPRIVATE_MEMSPACE_
+#define FTN_GET_GPRIVATE_LIMIT OMP_GET_GPRIVATE_LIMIT_
#define FTN_ALLOC OMP_ALLOC_
#define FTN_FREE OMP_FREE_
#define FTN_GET_DEVICE_NUM OMP_GET_DEVICE_NUM_
>From 9793e51bd2aaa2de278df8046dee668490836f28 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 23 Jul 2026 18:44:56 +0200
Subject: [PATCH 3/5] Add implementation for dyn_groupprivate routines
---
openmp/runtime/src/kmp_ftn_entry.h | 81 +++++++++++++++++++++++++++---
1 file changed, 74 insertions(+), 7 deletions(-)
diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h
index eebd08502728a..0f32f920ed65e 100644
--- a/openmp/runtime/src/kmp_ftn_entry.h
+++ b/openmp/runtime/src/kmp_ftn_entry.h
@@ -554,25 +554,92 @@ FTN_GET_SUBMEMSPACE(omp_memspace_handle_t KMP_DEREF memspace,
// The C (KMP_FTN_PLAIN) versions of the dynamic groupprivate information
// routines are defined in kmp_csupport.cpp, so only the Fortran entry points
// are generated here. The offset and access_group arguments are optional in
-// Fortran and are passed as null pointers when omitted. These stubs report that
-// no dynamic groupprivate block exists.
+// Fortran and are passed as null pointers when omitted; the defaults are a zero
+// offset and omp_access_cgroup.
+//
+// The dynamic-groupprivate-information routines report on the dynamic
+// groupprivate block that is instantiated by a dyn_groupprivate clause. When an
+// offload runtime is loaded it provides a device-aware definition; forward to
+// it so that Fortran code observes the same block as C/C++. When no offload
+// runtime is available the lookup resolves to the host entry in
+// kmp_csupport.cpp, which reports that no block exists (a null pointer, a size
+// of zero and a null memory space).
#if KMP_FTN_ENTRIES != KMP_FTN_PLAIN
-void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_PTR(size_t *, omp_access_t *) {
+void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_PTR(size_t *offset,
+ omp_access_t *access_group) {
+#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
+ return NULL;
+#else
+ void *(*fptr)(size_t, omp_access_t);
+ if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_ptr"))) {
+ size_t off = offset ? *offset : 0;
+ omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
+ return (*fptr)(off, ag);
+ }
return NULL;
+#endif
}
-void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_NOFB_PTR(size_t *, omp_access_t *) {
+void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_NOFB_PTR(size_t *offset,
+ omp_access_t *access_group) {
+#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return NULL;
+#else
+ void *(*fptr)(size_t, omp_access_t);
+ if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_nofb_ptr"))) {
+ size_t off = offset ? *offset : 0;
+ omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
+ return (*fptr)(off, ag);
+ }
+ return NULL;
+#endif
}
-size_t FTN_STDCALL FTN_GET_DYN_GPRIVATE_SIZE(omp_access_t *) { return 0; }
+size_t FTN_STDCALL FTN_GET_DYN_GPRIVATE_SIZE(omp_access_t *access_group) {
+#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
+ return 0;
+#else
+ size_t (*fptr)(omp_access_t);
+ if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_size"))) {
+ omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
+ return (*fptr)(ag);
+ }
+ return 0;
+#endif
+}
omp_memspace_handle_t FTN_STDCALL
-FTN_GET_DYN_GPRIVATE_MEMSPACE(omp_access_t *) {
+FTN_GET_DYN_GPRIVATE_MEMSPACE(omp_access_t *access_group) {
+#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
return omp_null_mem_space;
+#else
+ omp_memspace_handle_t (*fptr)(omp_access_t);
+ if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_memspace"))) {
+ omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
+ return (*fptr)(ag);
+ }
+ return omp_null_mem_space;
+#endif
}
-size_t FTN_STDCALL FTN_GET_GPRIVATE_LIMIT(int *, omp_access_t *) { return 0; }
+// The groupprivate limit is a per-device property. libomptarget, if loaded,
+// provides a device-aware omp_get_gprivate_limit; forward to it so that Fortran
+// code observes the same limits as C/C++. When no offload runtime is available
+// there are no non-host devices and the host reports no limit, so return zero.
+size_t FTN_STDCALL FTN_GET_GPRIVATE_LIMIT(int *device_num,
+ omp_access_t *access_group) {
+#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)
+ return 0;
+#else
+ size_t (*fptr)(int, omp_access_t);
+ if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_gprivate_limit"))) {
+ int dev = device_num ? *device_num : 0;
+ omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
+ return (*fptr)(dev, ag);
+ }
+ return 0;
+#endif
+}
#endif // KMP_FTN_ENTRIES != KMP_FTN_PLAIN
/* OpenMP 5.0 affinity format support */
>From 4eb4a3a32c2a54407f676918bc4df822ccef6714 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 23 Jul 2026 19:55:46 +0200
Subject: [PATCH 4/5] Add test
---
.../test/api/omp61_dyn_gprivate_routines.f90 | 69 +++++++++++++++++++
1 file changed, 69 insertions(+)
create mode 100644 openmp/runtime/test/api/omp61_dyn_gprivate_routines.f90
diff --git a/openmp/runtime/test/api/omp61_dyn_gprivate_routines.f90 b/openmp/runtime/test/api/omp61_dyn_gprivate_routines.f90
new file mode 100644
index 0000000000000..8db7eb65e60d9
--- /dev/null
+++ b/openmp/runtime/test/api/omp61_dyn_gprivate_routines.f90
@@ -0,0 +1,69 @@
+! RUN: %flang %flags %openmp_flags %s -o %t.exe
+! RUN: %t.exe | FileCheck %s
+
+! REQUIRES: linux
+
+! Test the Fortran interfaces of the OpenMP dynamic-groupprivate-information
+! routines and omp_get_gprivate_limit (TR15 Sec. 34.13).
+!
+! This exercises the interfaces, including the optional offset and access_group
+! arguments, and checks the values reported by the host runtime. When no dynamic
+! groupprivate block exists and no offload runtime is loaded, the routines report
+! a null pointer, a size of zero, a null memory space and a zero limit.
+
+program omp61_dyn_gprivate_routines
+ use omp_lib
+ use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t, c_int, c_associated
+ implicit none
+
+ type(c_ptr) :: p
+ integer(c_size_t) :: sz
+ integer(omp_memspace_handle_kind) :: ms
+ logical :: ok
+
+ ok = .true.
+
+ ! omp_get_dyn_gprivate_ptr: no block => null pointer. Cover default args,
+ ! explicit offset, explicit access_group, and the offset-omitted-via-keyword
+ ! form.
+ p = omp_get_dyn_gprivate_ptr()
+ if (c_associated(p)) ok = .false.
+ p = omp_get_dyn_gprivate_ptr(0_c_size_t)
+ if (c_associated(p)) ok = .false.
+ p = omp_get_dyn_gprivate_ptr(0_c_size_t, omp_access_cgroup)
+ if (c_associated(p)) ok = .false.
+ p = omp_get_dyn_gprivate_ptr(access_group=omp_access_cgroup)
+ if (c_associated(p)) ok = .false.
+
+ ! omp_get_dyn_gprivate_nofb_ptr: no block => null pointer.
+ p = omp_get_dyn_gprivate_nofb_ptr()
+ if (c_associated(p)) ok = .false.
+ p = omp_get_dyn_gprivate_nofb_ptr(0_c_size_t, omp_access_cgroup)
+ if (c_associated(p)) ok = .false.
+
+ ! omp_get_dyn_gprivate_size: no block => zero.
+ sz = omp_get_dyn_gprivate_size()
+ if (sz /= 0_c_size_t) ok = .false.
+ sz = omp_get_dyn_gprivate_size(omp_access_cgroup)
+ if (sz /= 0_c_size_t) ok = .false.
+
+ ! omp_get_dyn_gprivate_memspace: no block => omp_null_mem_space.
+ ms = omp_get_dyn_gprivate_memspace()
+ if (ms /= omp_null_mem_space) ok = .false.
+ ms = omp_get_dyn_gprivate_memspace(omp_access_cgroup)
+ if (ms /= omp_null_mem_space) ok = .false.
+
+ ! omp_get_gprivate_limit: the host reports no groupprivate limit.
+ sz = omp_get_gprivate_limit(0_c_int)
+ if (sz /= 0_c_size_t) ok = .false.
+ sz = omp_get_gprivate_limit(0_c_int, omp_access_cgroup)
+ if (sz /= 0_c_size_t) ok = .false.
+
+ if (ok) then
+ print *, "PASS"
+ else
+ print *, "FAIL"
+ end if
+
+! CHECK: PASS
+end program omp61_dyn_gprivate_routines
\ No newline at end of file
>From 24294cc8de75efa2ff761953147eddaa95f4e343 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Wed, 30 Sep 2026 19:23:53 +0200
Subject: [PATCH 5/5] Correct dlsym logic.
---
openmp/runtime/src/kmp_ftn_entry.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h
index 0f32f920ed65e..ae83689cecd3c 100644
--- a/openmp/runtime/src/kmp_ftn_entry.h
+++ b/openmp/runtime/src/kmp_ftn_entry.h
@@ -571,7 +571,7 @@ void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_PTR(size_t *offset,
return NULL;
#else
void *(*fptr)(size_t, omp_access_t);
- if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_ptr"))) {
+ if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_dyn_gprivate_ptr"))) {
size_t off = offset ? *offset : 0;
omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
return (*fptr)(off, ag);
@@ -586,7 +586,7 @@ void *FTN_STDCALL FTN_GET_DYN_GPRIVATE_NOFB_PTR(size_t *offset,
return NULL;
#else
void *(*fptr)(size_t, omp_access_t);
- if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_nofb_ptr"))) {
+ if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_dyn_gprivate_nofb_ptr"))) {
size_t off = offset ? *offset : 0;
omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
return (*fptr)(off, ag);
@@ -600,7 +600,7 @@ size_t FTN_STDCALL FTN_GET_DYN_GPRIVATE_SIZE(omp_access_t *access_group) {
return 0;
#else
size_t (*fptr)(omp_access_t);
- if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_size"))) {
+ if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_dyn_gprivate_size"))) {
omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
return (*fptr)(ag);
}
@@ -614,7 +614,7 @@ FTN_GET_DYN_GPRIVATE_MEMSPACE(omp_access_t *access_group) {
return omp_null_mem_space;
#else
omp_memspace_handle_t (*fptr)(omp_access_t);
- if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_dyn_gprivate_memspace"))) {
+ if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_dyn_gprivate_memspace"))) {
omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
return (*fptr)(ag);
}
@@ -632,7 +632,7 @@ size_t FTN_STDCALL FTN_GET_GPRIVATE_LIMIT(int *device_num,
return 0;
#else
size_t (*fptr)(int, omp_access_t);
- if ((*(void **)(&fptr) = KMP_DLSYM("omp_get_gprivate_limit"))) {
+ if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_gprivate_limit"))) {
int dev = device_num ? *device_num : 0;
omp_access_t ag = access_group ? *access_group : omp_access_cgroup;
return (*fptr)(dev, ag);
More information about the Openmp-commits
mailing list