[Openmp-commits] [llvm] [openmp] [OpenACC] Prototype OpenMP 5.1's omp_target_is_accessible (PR #143058)

via Openmp-commits openmp-commits at lists.llvm.org
Thu Jun 5 20:07:13 PDT 2025


https://github.com/yuanm-qy created https://github.com/llvm/llvm-project/pull/143058

 These changes originate from the clacc project
 Original author: Joel E. Denny
 Original commit: 198fde1b27b808a5d9a4e77ee68471b1628af9eb

 I require the omp_target_is_accessible functionality for current development, so I'm submitting Joel E. Denny's implementation for community review. This contribution:

 1. Implements OpenMP 5.1's omp_target_is_accessible interface
 2. Introduces device memory accessibility verification logic
 3. Requests technical validation for:
 - Edge case handling (Size=0 scenarios)
 - NULL pointer behavior specification
 - Compatibility with shared memory architectures

 Please help verify implementation correctness against OpenMP specifications.

>From 0cecb7af5ce0ad643f9aa64b37f1d3d333d9f1e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cyuanming=E2=80=9D?= <“17865912817 at 163.com”>
Date: Fri, 6 Jun 2025 10:59:29 +0800
Subject: [PATCH] [OpenACC] Prototype OpenMP 5.1's omp_target_is_accessible 
 These changes originate from the clacc project  Original author: Joel E.
 Denny  Original commit: 198fde1b27b808a5d9a4e77ee68471b1628af9eb

 I require the omp_target_is_accessible functionality for current development, so I'm submitting Joel E. Denny's implementation for community review. This contribution:

 1. Implements OpenMP 5.1's omp_target_is_accessible interface
 2. Introduces device memory accessibility verification logic
 3. Requests technical validation for:
 - Edge case handling (Size=0 scenarios)
 - NULL pointer behavior specification
 - Compatibility with shared memory architectures

 Please help verify implementation correctness against OpenMP specifications.
---
 offload/include/omptarget.h         |  1 +
 offload/libomptarget/OpenMP/API.cpp | 57 +++++++++++++++++++++++++++++
 offload/libomptarget/exports        |  1 +
 openmp/runtime/src/kmp_ftn_os.h     |  4 ++
 4 files changed, 63 insertions(+)

diff --git a/offload/include/omptarget.h b/offload/include/omptarget.h
index 6971780c7bdb5..8af8c4f659b35 100644
--- a/offload/include/omptarget.h
+++ b/offload/include/omptarget.h
@@ -280,6 +280,7 @@ int omp_get_initial_device(void);
 void *omp_target_alloc(size_t Size, int DeviceNum);
 void omp_target_free(void *DevicePtr, int DeviceNum);
 int omp_target_is_present(const void *Ptr, int DeviceNum);
+int omp_target_is_accessible(const void *Ptr, size_t Size, int DeviceNum);
 int omp_target_memcpy(void *Dst, const void *Src, size_t Length,
                       size_t DstOffset, size_t SrcOffset, int DstDevice,
                       int SrcDevice);
diff --git a/offload/libomptarget/OpenMP/API.cpp b/offload/libomptarget/OpenMP/API.cpp
index 4576f9bd06121..936c366e7e3a3 100644
--- a/offload/libomptarget/OpenMP/API.cpp
+++ b/offload/libomptarget/OpenMP/API.cpp
@@ -683,3 +683,60 @@ EXTERN void *omp_get_mapped_ptr(const void *Ptr, int DeviceNum) {
 
   return TPR.TargetPointer;
 }
+
+EXTERN int omp_target_is_accessible(const void *Ptr, size_t Size,
+                                    int DeviceNum) {
+  TIMESCOPE();
+  // OpenMP 5.1, sec. 3.8.4 "omp_target_is_accessible", p. 417, L21-22:
+  // "This routine returns true if the storage of size bytes starting at the
+  // address given by Ptr is accessible from device device_num. Otherwise, it
+  // returns false."
+  //
+  // The meaning of "accessible" for unified shared memory is established in
+  // OpenMP 5.1, sec. 2.5.1 "requires directive".  More generally, the specified
+  // host memory is accessible if it can be accessed from the device either
+  // directly (because of unified shared memory or because DeviceNum is the
+  // value returned by omp_get_initial_device()) or indirectly (because it's
+  // mapped to the device).
+  DP("Call to omp_target_is_accessible for device %d and address " DPxMOD "\n",
+     DeviceNum, DPxPTR(Ptr));
+
+  // FIXME: Is this right?
+  //
+  // Null pointer is permitted:
+  //
+  // OpenMP 5.1, sec. 3.8.4 "omp_target_is_accessible", p. 417, L15:
+  // "The value of ptr must be a valid host pointer or NULL (or C_NULL_PTR, for
+  // Fortran)."
+  //
+  // However, I found no specification of behavior in this case.
+  // omp_target_is_present has the same problem and is implemented the same way.
+  // Should Size have any effect on the result when Ptr is NULL?
+  if (!Ptr) {
+    DP("Call to omp_target_is_accessible with NULL Ptr, returning false\n");
+    return false;
+  }
+
+  if (DeviceNum == omp_get_initial_device()) {
+    DP("Call to omp_target_is_accessible on host, returning true\n");
+    return true;
+  }
+  
+  auto DeviceOrErr = PM->getDevice(DeviceNum);
+  if (!DeviceOrErr)
+    FATAL_MESSAGE(DeviceNum, "%s", toString(DeviceOrErr.takeError()).c_str());
+
+  // TODO: How does the spec intend for the Size=0 case to be handled?
+  // Currently, for the case where arr[N:M] is mapped, we return true for any
+  // address within arr[0:N+M].  However, Size>1 returns true only for arr[N:M].
+  // This is based on the discussion so far at the time of this writing at
+  // <https://github.com/llvm/llvm-project/issues/54899>.  If the behavior
+  // changes, keep comments for omp_get_accessible_buffer in omp.h.var in sync.
+  TargetPointerResultTy TPR =
+      DeviceOrErr->getMappingInfo().getTgtPtrBegin(const_cast<void *>(Ptr), Size,
+                                                   /*UpdateRefCount=*/false,
+                                                   /*UseHoldRefCount=*/false);
+  int Rc = TPR.isPresent();
+  DP("Call to omp_target_is_accessible returns %d\n", Rc);
+  return Rc;
+}
\ No newline at end of file
diff --git a/offload/libomptarget/exports b/offload/libomptarget/exports
index 2406776c1fb5f..236efd263f7ce 100644
--- a/offload/libomptarget/exports
+++ b/offload/libomptarget/exports
@@ -43,6 +43,7 @@ VERS1.0 {
     omp_target_alloc;
     omp_target_free;
     omp_target_is_present;
+    omp_target_is_accessible;
     omp_target_memcpy;
     omp_target_memcpy_rect;
     omp_target_memcpy_async;
diff --git a/openmp/runtime/src/kmp_ftn_os.h b/openmp/runtime/src/kmp_ftn_os.h
index ae0ed067235e5..46afa800379e0 100644
--- a/openmp/runtime/src/kmp_ftn_os.h
+++ b/openmp/runtime/src/kmp_ftn_os.h
@@ -114,6 +114,7 @@
 #define FTN_TARGET_ALLOC omp_target_alloc
 #define FTN_TARGET_FREE omp_target_free
 #define FTN_TARGET_IS_PRESENT omp_target_is_present
+#define FTN_TARGET_IS_ACCESSIBLE omp_target_is_accessible
 #define FTN_TARGET_MEMCPY omp_target_memcpy
 #define FTN_TARGET_MEMCPY_RECT omp_target_memcpy_rect
 #define FTN_TARGET_MEMSET omp_target_memset
@@ -263,6 +264,7 @@
 #define FTN_TARGET_ALLOC omp_target_alloc_
 #define FTN_TARGET_FREE omp_target_free_
 #define FTN_TARGET_IS_PRESENT omp_target_is_present_
+#define FTN_TARGET_IS_ACCESSIBLE omp_target_is_accessible_
 #define FTN_TARGET_MEMCPY omp_target_memcpy_
 #define FTN_TARGET_MEMCPY_RECT omp_target_memcpy_rect_
 #define FTN_TARGET_ASSOCIATE_PTR omp_target_associate_ptr_
@@ -412,6 +414,7 @@
 #define FTN_TARGET_ALLOC OMP_TARGET_ALLOC
 #define FTN_TARGET_FREE OMP_TARGET_FREE
 #define FTN_TARGET_IS_PRESENT OMP_TARGET_IS_PRESENT
+#define FTN_TARGET_IS_ACCESSIBLE OMP_TARGET_IS_ACCESSIBLE
 #define FTN_TARGET_MEMCPY OMP_TARGET_MEMCPY
 #define FTN_TARGET_MEMCPY_RECT OMP_TARGET_MEMCPY_RECT
 #define FTN_TARGET_ASSOCIATE_PTR OMP_TARGET_ASSOCIATE_PTR
@@ -559,6 +562,7 @@
 #define FTN_TARGET_ALLOC OMP_TARGET_ALLOC_
 #define FTN_TARGET_FREE OMP_TARGET_FREE_
 #define FTN_TARGET_IS_PRESENT OMP_TARGET_IS_PRESENT_
+#define FTN_TARGET_IS_ACCESSIBLE OMP_TARGET_IS_ACCESSIBLE_
 #define FTN_TARGET_MEMCPY OMP_TARGET_MEMCPY_
 #define FTN_TARGET_MEMCPY_RECT OMP_TARGET_MEMCPY_RECT_
 #define FTN_TARGET_ASSOCIATE_PTR OMP_TARGET_ASSOCIATE_PTR_



More information about the Openmp-commits mailing list