Now also with attached patch …

Tobias Burnus wrote:
This is a collateral patch from working on an update for the
implementation status, namely on adding the TR14 (OpenMP 6.1)
additions to https://gcc.gnu.org/onlinedocs/libgomp/OpenMP-Implementation-Status.html

Actually, I missed this feature myself - most of the time
when calling API routines that take a device number as argument;
'0' feels wrong – and 'omp_get_default_device()' is somewhat
lengthy. In any case, this patch adds this extremely low
hanging fruit.

Comments before I commit it?

Tobias

PS: This only adds omp_default_device; the PR also mentions
some cleanup tasks, but that's deferred to later.
OpenMP: Add omp_default_device named constant [PR119677]

OpenMP TR 14 (OpenMP 6.1) adds omp_default_device < -1 as
named constant alongside omp_initial_device and omp_default_device.

GCC supports it already internally via GOMP_DEVICE_DEFAULT_OMP_61,
but this patch now adds the omp_default_device enum/PARAMETER to
omp.h / omp_lib.

Note that PR119677 requests some cleanups, which still have to be
done.

	PR libgomp/119677

gcc/fortran/ChangeLog:

	* intrinsic.texi (OpenMP Modules): Add omp_default_device.
	* openmp.cc (gfc_resolve_omp_context_selector): Accept
	omp_default_device as conforming device number.

libgomp/ChangeLog:

	* omp.h.in (omp_default_device): New enum value.
	* omp_lib.f90.in: New parameter.
	* omp_lib.h.in: Likewise
	* target.c (gomp_get_default_device): New. Split off from ...
	(resolve_device): ... here; call it.
	(omp_target_alloc, omp_target_free, omp_target_is_present,
	omp_target_memcpy_check, omp_target_memset, omp_target_memset_async,
	omp_target_associate_ptr, omp_get_mapped_ptr,
	omp_target_is_accessible, omp_pause_resource,
	omp_get_uid_from_device): Handle omp_default_device.
	* testsuite/libgomp.c/device_uid.c: Likewise.
	* testsuite/libgomp.fortran/device_uid.f90: Likewise.
	* testsuite/libgomp.c-c++-common/omp-default-device.c: New test.
	* testsuite/libgomp.fortran/omp-default-device.f90: New test.

 gcc/fortran/intrinsic.texi                         |  1 +
 gcc/fortran/openmp.cc                              |  6 ++-
 libgomp/omp.h.in                                   |  3 +-
 libgomp/omp_lib.f90.in                             |  1 +
 libgomp/omp_lib.h.in                               |  3 +-
 libgomp/target.c                                   | 48 +++++++++++++++--
 .../libgomp.c-c++-common/omp-default-device.c      | 59 +++++++++++++++++++++
 libgomp/testsuite/libgomp.c/device_uid.c           |  4 +-
 libgomp/testsuite/libgomp.fortran/device_uid.f90   |  5 +-
 .../libgomp.fortran/omp-default-device.f90         | 61 ++++++++++++++++++++++
 10 files changed, 180 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index b2d1e455988..69cf10caf9d 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -16250,6 +16250,7 @@ The following scalar default-integer named constants:
 @table @asis
 @item @code{omp_initial_device}
 @item @code{omp_invalid_device}
+@item @code{omp_default_device}
 @end table
 
 
diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc
index 770bc5b1200..9c9d0c2c534 100644
--- a/gcc/fortran/openmp.cc
+++ b/gcc/fortran/openmp.cc
@@ -12290,12 +12290,14 @@ gfc_resolve_omp_context_selector (gfc_omp_set_selector *oss,
 		continue;
 	      }
 	    /* Device number must be conforming, which includes
-	       omp_initial_device (-1) and omp_invalid_device (-4).  */
+	       omp_initial_device (-1), omp_invalid_device (-4),
+	       and omp_default_device (-5).  */
 	    if (property_kind == OMP_TRAIT_PROPERTY_DEV_NUM_EXPR
 		&& otp->expr->expr_type == EXPR_CONSTANT
 		&& mpz_sgn (otp->expr->value.integer) < 0
 		&& mpz_cmp_si (otp->expr->value.integer, -1) != 0
-		&& mpz_cmp_si (otp->expr->value.integer, -4) != 0)
+		&& mpz_cmp_si (otp->expr->value.integer, -4) != 0
+		&& mpz_cmp_si (otp->expr->value.integer, -5) != 0)
 	      gfc_error ("property must be a conforming device number at %L",
 			 &otp->expr->where);
 	    break;
diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in
index 60cb2b21be7..566a3c28b94 100644
--- a/libgomp/omp.h.in
+++ b/libgomp/omp.h.in
@@ -189,7 +189,8 @@ typedef enum omp_event_handle_t __GOMP_UINTPTR_T_ENUM
 enum
 {
   omp_initial_device = -1,
-  omp_invalid_device = -4
+  omp_invalid_device = -4,
+  omp_default_device = -5
 };
 
 typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in
index ce866c00121..74e0bfea344 100644
--- a/libgomp/omp_lib.f90.in
+++ b/libgomp/omp_lib.f90.in
@@ -176,6 +176,7 @@
                  parameter :: omp_low_lat_mem_space = 4
         integer, parameter :: omp_initial_device = -1
         integer, parameter :: omp_invalid_device = -4
+        integer, parameter :: omp_default_device = -5
         integer (omp_interop_kind), &
                  parameter :: omp_interop_none = 0_omp_interop_kind
         integer (omp_interop_fr_kind), parameter :: omp_ifr_cuda = 1
diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in
index 9047095c5e0..9422515dc37 100644
--- a/libgomp/omp_lib.h.in
+++ b/libgomp/omp_lib.h.in
@@ -182,9 +182,10 @@
       parameter (omp_const_mem_space = 2)
       parameter (omp_high_bw_mem_space = 3)
       parameter (omp_low_lat_mem_space = 4)
-      integer omp_initial_device, omp_invalid_device
+      integer omp_initial_device, omp_invalid_device, omp_default_device
       parameter (omp_initial_device = -1)
       parameter (omp_invalid_device = -4)
+      parameter (omp_default_device = -5)
       integer (omp_interop_kind) omp_interop_none
       parameter (omp_interop_none = 0_omp_interop_kind)
       integer (omp_interop_fr_kind) omp_ifr_cuda
diff --git a/libgomp/target.c b/libgomp/target.c
index ac5b4b0b720..002a144b4ab 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -139,6 +139,14 @@ gomp_get_num_devices (void)
   return num_devices_openmp;
 }
 
+static int
+gomp_get_default_device ()
+{
+  gomp_init_targets_once ();
+  struct gomp_task_icv *icv = gomp_icv (false);
+  return icv->default_device_var;
+}
+
 static struct gomp_device_descr *
 resolve_device (int device_id, bool remapped)
 {
@@ -148,11 +156,7 @@ resolve_device (int device_id, bool remapped)
 
   if ((remapped && device_id == GOMP_DEVICE_ICV)
       || device_id == GOMP_DEVICE_DEFAULT_OMP_61)
-    {
-      struct gomp_task_icv *icv = gomp_icv (false);
-      device_id = icv->default_device_var;
-      remapped = false;
-    }
+    device_id = gomp_get_default_device ();
 
   if (device_id < 0)
     {
@@ -4653,6 +4657,9 @@ GOMP_teams4 (unsigned int num_teams_low, unsigned int num_teams_high,
 void *
 omp_target_alloc (size_t size, int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ())
     return malloc (size);
@@ -4674,6 +4681,9 @@ omp_target_alloc (size_t size, int device_num)
 void
 omp_target_free (void *device_ptr, int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ())
     {
@@ -4811,6 +4821,9 @@ gomp_page_locked_host_free (void *ptr)
 int
 omp_target_is_present (const void *ptr, int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ())
     return 1;
@@ -4843,6 +4856,11 @@ omp_target_memcpy_check (int dst_device_num, int src_device_num,
 			 struct gomp_device_descr **dst_devicep,
 			 struct gomp_device_descr **src_devicep)
 {
+  if (dst_device_num == omp_default_device)
+    dst_device_num = gomp_get_default_device ();
+  if (src_device_num == omp_default_device)
+    src_device_num = gomp_get_default_device ();
+
   if (dst_device_num != gomp_get_num_devices ()
       /* Above gomp_get_num_devices has to be called unconditionally.  */
       && dst_device_num != omp_initial_device)
@@ -5323,6 +5341,9 @@ omp_target_memset_int (void *ptr, int val, size_t count,
 void*
 omp_target_memset (void *ptr, int val, size_t count, int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   struct gomp_device_descr *devicep;
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ()
@@ -5359,6 +5380,9 @@ omp_target_memset_async (void *ptr, int val, size_t count, int device_num,
   unsigned flags = 0;
   int i;
 
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ()
       || (devicep = resolve_device (device_num, false)) == NULL
@@ -5387,6 +5411,9 @@ int
 omp_target_associate_ptr (const void *host_ptr, const void *device_ptr,
 			  size_t size, size_t device_offset, int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ())
     return EINVAL;
@@ -5484,6 +5511,9 @@ omp_target_disassociate_ptr (const void *ptr, int device_num)
 void *
 omp_get_mapped_ptr (const void *ptr, int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num == omp_initial_device
       || device_num == omp_get_initial_device ())
     return (void *) ptr;
@@ -5520,6 +5550,9 @@ omp_get_mapped_ptr (const void *ptr, int device_num)
 int
 omp_target_is_accessible (const void *ptr, size_t size, int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ())
     return true;
@@ -5537,6 +5570,8 @@ int
 omp_pause_resource (omp_pause_resource_t kind, int device_num)
 {
   (void) kind;
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
   if (device_num == omp_initial_device
       || device_num == gomp_get_num_devices ())
     return gomp_pause_host ();
@@ -5847,6 +5882,9 @@ gomp_get_uid_for_device (struct gomp_device_descr *devicep, int device_num)
 const char *
 omp_get_uid_from_device (int device_num)
 {
+  if (device_num == omp_default_device)
+    device_num = gomp_get_default_device ();
+
   if (device_num < omp_initial_device || device_num > gomp_get_num_devices ())
     return NULL;
 
diff --git a/libgomp/testsuite/libgomp.c-c++-common/omp-default-device.c b/libgomp/testsuite/libgomp.c-c++-common/omp-default-device.c
new file mode 100644
index 00000000000..5489f019b0b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/omp-default-device.c
@@ -0,0 +1,59 @@
+#include <omp.h>
+
+#if __cplusplus
+static_assert (omp_default_device < -1
+	       && omp_default_device != omp_invalid_device, "");
+#else
+_Static_assert (omp_default_device < -1
+		&& omp_default_device != omp_invalid_device, "");
+#endif
+
+static int
+is_same_dev (int d1, int d2)
+{
+  int num_dev = omp_get_num_devices ();
+  if (d1 == omp_initial_device)
+    d1 = num_dev;
+  if (d2 == omp_initial_device)
+    d2 = num_dev;
+  return (d1 == d2);
+}
+
+int
+main()
+{
+  int dev = -99;
+  int def_dev = omp_get_default_device ();
+  #pragma omp target map(from: dev) device(omp_default_device)
+    dev = omp_get_device_num ();
+
+  if (!is_same_dev (def_dev, dev))
+    __builtin_abort ();
+
+  for (def_dev = omp_initial_device; def_dev <= omp_get_num_devices ();
+       def_dev++)
+    {
+      const char* uid = omp_get_uid_from_device(def_dev);
+      omp_set_default_device (def_dev);
+      dev = -99;
+      #pragma omp target map(from: dev) device(omp_default_device)
+        dev = omp_get_device_num ();
+      if (!is_same_dev (def_dev, dev))
+        __builtin_abort ();
+
+      /* Shall not modify the ICV.  */
+      omp_set_default_device (omp_default_device);
+      if (def_dev != omp_get_default_device ())
+        __builtin_abort ();
+
+      /* Assume the ptr and no only the string is the same.  */
+      if (uid != omp_get_uid_from_device (omp_default_device))
+        __builtin_abort ();
+    }
+
+  omp_set_default_device (omp_invalid_device);
+  /* Shall not modify the ICV.  */
+  omp_set_default_device (omp_default_device);
+  if (omp_invalid_device != omp_get_default_device ())
+    __builtin_abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c/device_uid.c b/libgomp/testsuite/libgomp.c/device_uid.c
index 0412d06f615..83aba0f6a91 100644
--- a/libgomp/testsuite/libgomp.c/device_uid.c
+++ b/libgomp/testsuite/libgomp.c/device_uid.c
@@ -5,10 +5,12 @@
 int main()
 {
   const char **strs = (const char **) malloc (sizeof (char*) * (omp_get_num_devices () + 1));
-  for (int i = omp_invalid_device - 1; i <= omp_get_num_devices () + 1; i++)
+  for (int i = omp_default_device - 1; i <= omp_get_num_devices () + 1; i++)
     {
       const char *str = omp_get_uid_from_device (i);
       int dev = omp_get_device_from_uid (str);
+      if (i == omp_default_device)
+	i = omp_get_default_device ();
 // __builtin_printf("%i -> %s -> %d\n", i, str, dev);
       if (i < omp_initial_device || i > omp_get_num_devices ())
 	{
diff --git a/libgomp/testsuite/libgomp.fortran/device_uid.f90 b/libgomp/testsuite/libgomp.fortran/device_uid.f90
index 504f6caaf07..9bc02e4b8e6 100644
--- a/libgomp/testsuite/libgomp.fortran/device_uid.f90
+++ b/libgomp/testsuite/libgomp.fortran/device_uid.f90
@@ -10,10 +10,13 @@ program main
 
   allocate(strs(0:omp_get_num_devices ()))
 
-  do i = omp_invalid_device - 1, omp_get_num_devices () + 1
+  do j = omp_default_device - 1, omp_get_num_devices () + 1
+    i = j
     str => omp_get_uid_from_device (i)
     dev = omp_get_device_from_uid (str)
 ! print *, i, str, dev
+    if (i == omp_default_device) &
+      i = omp_get_default_device ()
     if (i < omp_initial_device .or. i > omp_get_num_devices ()) then
       if (dev /= omp_invalid_device .or. associated(str)) &
         stop 1
diff --git a/libgomp/testsuite/libgomp.fortran/omp-default-device.f90 b/libgomp/testsuite/libgomp.fortran/omp-default-device.f90
new file mode 100644
index 00000000000..28e3496d547
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/omp-default-device.f90
@@ -0,0 +1,61 @@
+program main
+  use omp_lib
+  implicit none (type, external)
+  integer :: dev, def_dev
+
+  if (omp_default_device >= -1 .or. omp_default_device == omp_invalid_device) &
+    error stop 1
+
+  dev = -99
+  def_dev = omp_get_default_device ()
+  !$omp target map(from: dev) device(omp_default_device)
+    dev = omp_get_device_num ()
+  !$omp end target
+
+  if (.not.is_same_dev (def_dev, dev)) &
+    error stop 2
+
+  do def_dev = omp_initial_device, omp_get_num_devices ()
+  block
+    character(:), pointer :: uid
+
+    uid => omp_get_uid_from_device(def_dev)
+    call omp_set_default_device (def_dev)
+    dev = -99
+    !$omp target map(from: dev) device(omp_default_device)
+      dev = omp_get_device_num ()
+    !$omp end target
+    if (.not.is_same_dev (def_dev, dev)) &
+      error stop 3
+
+    ! Shall not modify the ICV.  */
+    call omp_set_default_device (omp_default_device)
+    if (def_dev /= omp_get_default_device ()) &
+      error stop 4
+
+    ! Assume the ptr and no only the string is the same.  */
+    if (.not.associated(uid, omp_get_uid_from_device (omp_default_device))) &
+      error stop 5
+  end block
+  end do
+
+  call omp_set_default_device (omp_invalid_device)
+  ! Shall not modify the ICV.
+  call omp_set_default_device (omp_default_device)
+  if (omp_invalid_device /= omp_get_default_device ()) &
+    error stop 6
+
+contains
+
+  logical function is_same_dev (d1, d2)
+    integer, value :: d1, d2
+    integer :: num_dev
+
+    num_dev = omp_get_num_devices ()
+    if (d1 == omp_initial_device) &
+      d1 = num_dev
+    if (d2 == omp_initial_device) &
+      d2 = num_dev
+    is_same_dev = d1 == d2
+  end function is_same_dev
+end program

Reply via email to