https://gcc.gnu.org/g:0f77d88fdf797842ac0134a4013b4227dd5a658f

commit r15-9314-g0f77d88fdf797842ac0134a4013b4227dd5a658f
Author: Tobias Burnus <tbur...@baylibre.com>
Date:   Tue Apr 8 13:47:53 2025 +0200

    OpenMP: Fix append_args handling in modify_call_for_omp_dispatch
    
    At tree level, the addr ref is also required for array dummy arguments,
    contrary to C; the GOMP_interop calls in modify_call_for_omp_dispatch
    were updated accordingly (using build_fold_addr_expr).
    
    As the GOMP_interop calls had no location data associated with them,
    the init call happened as soon as executing the previous line of code,
    which was confusing; solution: use the location data of the function
    call itself.
    
            PR middle-end/119662
    
    gcc/ChangeLog:
    
            * gimplify.cc (modify_call_for_omp_dispatch): Fix GOMP_interop
            arg passing; add location info to function calls.
    
    libgomp/ChangeLog:
    
            * testsuite/libgomp.c/append-args-fr-1.c: New test.
            * testsuite/libgomp.c/append-args-fr.h: New test.
    
    gcc/testsuite/ChangeLog:
            * c-c++-common/gomp/append-args-interop.c: Update for fixed
            GOMP_interop call.
            * g++.dg/gomp/append-args-8.C: Likewise.
            * gfortran.dg/gomp/append-args-interop.f90: Likewise.

Diff:
---
 gcc/gimplify.cc                                    |  32 ++-
 .../c-c++-common/gomp/append-args-interop.c        |   4 +-
 gcc/testsuite/g++.dg/gomp/append-args-8.C          |   8 +-
 .../gfortran.dg/gomp/append-args-interop.f90       |   4 +-
 libgomp/testsuite/libgomp.c/append-args-fr-1.c     | 232 ++++++++++++++++
 libgomp/testsuite/libgomp.c/append-args-fr.h       | 305 +++++++++++++++++++++
 6 files changed, 563 insertions(+), 22 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 51595f6f51e4..4f385b1b779b 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -3887,6 +3887,7 @@ static tree
 modify_call_for_omp_dispatch (tree expr, tree dispatch_clauses,
                              bool want_value, bool pointerize)
 {
+  location_t loc = EXPR_LOCATION (expr);
   tree fndecl = get_callee_fndecl (expr);
 
   /* Skip processing if we don't get the expected call form.  */
@@ -4081,14 +4082,17 @@ modify_call_for_omp_dispatch (tree expr, tree 
dispatch_clauses,
                }
            }
 
+         objs = build_fold_addr_expr (objs);
+         target_tgtsync = build_fold_addr_expr (target_tgtsync);
+         prefer_type = prefer_type ? build_fold_addr_expr (prefer_type)
+                                   : null_pointer_node;
          tree fn = builtin_decl_explicit (BUILT_IN_GOMP_INTEROP);
          tree create
-           = build_call_expr (fn, 11, dispatch_device_num,
-                              nobjs, objs, target_tgtsync,
-                              prefer_type ? prefer_type : null_pointer_node,
-                              integer_zero_node, null_pointer_node,
-                              integer_zero_node, null_pointer_node,
-                              integer_zero_node, null_pointer_node);
+           = build_call_expr_loc (loc, fn, 11, dispatch_device_num,
+                                  nobjs, objs, target_tgtsync, prefer_type,
+                                  integer_zero_node, null_pointer_node,
+                                  integer_zero_node, null_pointer_node,
+                                  integer_zero_node, null_pointer_node);
          if (init_code)
            init_code = build2 (COMPOUND_EXPR, TREE_TYPE (create),
                                init_code, create);
@@ -4096,12 +4100,12 @@ modify_call_for_omp_dispatch (tree expr, tree 
dispatch_clauses,
            init_code = create;
 
          cleanup
-           = build_call_expr (fn, 11, dispatch_device_num,
-                              integer_zero_node, null_pointer_node,
-                              null_pointer_node, null_pointer_node,
-                              integer_zero_node, null_pointer_node,
-                              nobjs, objs,
-                              integer_zero_node, null_pointer_node);
+           = build_call_expr_loc (loc, fn, 11, dispatch_device_num,
+                                  integer_zero_node, null_pointer_node,
+                                  null_pointer_node, null_pointer_node,
+                                  integer_zero_node, null_pointer_node,
+                                  nobjs, objs,
+                                  integer_zero_node, null_pointer_node);
          if (clobbers)
            cleanup = build2 (COMPOUND_EXPR, TREE_TYPE (clobbers),
                              cleanup, clobbers);
@@ -4282,8 +4286,8 @@ modify_call_for_omp_dispatch (tree expr, tree 
dispatch_clauses,
                                       actual_ptr);
                }
              tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_MAPPED_PTR);
-             tree mapped_arg = build_call_expr (fn, 2, actual_ptr,
-                                                dispatch_device_num);
+             tree mapped_arg = build_call_expr_loc (loc, fn, 2, actual_ptr,
+                                                    dispatch_device_num);
 
              if (TREE_CODE (*arg_p) == ADDR_EXPR
                  || (TREE_CODE (TREE_TYPE (actual_ptr)) == REFERENCE_TYPE))
diff --git a/gcc/testsuite/c-c++-common/gomp/append-args-interop.c 
b/gcc/testsuite/c-c++-common/gomp/append-args-interop.c
index 1211450ce63e..e9b1ed43c07d 100644
--- a/gcc/testsuite/c-c++-common/gomp/append-args-interop.c
+++ b/gcc/testsuite/c-c++-common/gomp/append-args-interop.c
@@ -39,6 +39,6 @@ test (int *a, int *b)
   return x;
 }
 
-/* { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(D\.\[0-9\]+, 2, 
interopobjs\.\[0-9\]+, tgt_tgtsync\.\[0-9\]+," "gimple" } } */
-/* { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(D\.\[0-9\]+, 0, 0B, 
0B, 0B, 0, 0B, 2, interopobjs\.\[0-9\]+," "gimple" } } */
+/* { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(D\.\[0-9\]+, 2, 
&interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+," "gimple" } } */
+/* { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(D\.\[0-9\]+, 0, 0B, 
0B, 0B, 0, 0B, 2, &interopobjs\.\[0-9\]+," "gimple" } } */
 /* { dg-final { scan-tree-dump "repl1 \\(obj1, interop\.\[0-9\]+, 
interop\.\[0-9\]+\\)" "gimple" } } */
diff --git a/gcc/testsuite/g++.dg/gomp/append-args-8.C 
b/gcc/testsuite/g++.dg/gomp/append-args-8.C
index 379c7677c95a..3052c5b75b30 100644
--- a/gcc/testsuite/g++.dg/gomp/append-args-8.C
+++ b/gcc/testsuite/g++.dg/gomp/append-args-8.C
@@ -82,11 +82,11 @@ test (int *a, int *b)
 /* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device 
\\(D\.\[0-9\]+\\);" 2 "gimple" } }  */
 /* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = 
__builtin_omp_get_mapped_ptr \\(a, D\.\[0-9\]+\\);" 1 "gimple" } }  */
 
-/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 
1, interopobjs\.\[0-9\], tgt_tgtsync\.\[0-9\]+, pref_type.2, 0, 0B, 0, 0B, 0, 
0B\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 
1, &interopobjs\.\[0-9\], &tgt_tgtsync\.\[0-9\]+, &pref_type.2, 0, 0B, 0, 0B, 
0, 0B\\);" 1 "gimple" } }  */
 /* { dg-final { scan-tree-dump-times "repl2<int\\*, int\\*, omp_interop_t> 
\\(b, D\.\[0-9\]+, obj1, interop\.\[0-9\]+\\);" 1 "gimple" } }  */
-/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 
0, 0B, 0B, 0B, 0, 0B, 1, interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 
0, 0B, 0B, 0B, 0, 0B, 1, &interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } }  */
 
 
-/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 
0B, 0, 0B, 3, interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 
0B, 0, 0B, 3, &interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } }  */
 /* { dg-final { scan-tree-dump-times "repl3<int\\*, omp_interop_t> \\(a, 
interop\.\[0-9\]+, interop\.\[0-9\]+, interop\.\[0-9\]+, 1, 2, \"abc\"\\);" 1 
"gimple" } }  */
-/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 3, 
interopobjs\.\[0-9\]+, tgt_tgtsync\.\[0-9\]+, pref_type\.\[0-9\]+, 0, 0B, 0, 
0B, 0, 0B\\);" 1 "gimple" } }  */
+/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 3, 
&interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, &pref_type\.\[0-9\]+, 0, 0B, 0, 
0B, 0, 0B\\);" 1 "gimple" } }  */
diff --git a/gcc/testsuite/gfortran.dg/gomp/append-args-interop.f90 
b/gcc/testsuite/gfortran.dg/gomp/append-args-interop.f90
index f2c4d9714647..540079a28ac6 100644
--- a/gcc/testsuite/gfortran.dg/gomp/append-args-interop.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/append-args-interop.f90
@@ -23,6 +23,6 @@ use m
   call f()
 end
 
-! { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(99, 3, 
interopobjs\.\[0-9\]+, tgt_tgtsync\.\[0-9\]+, pref_type\.\[0-9\]+, " "gimple" } 
}
-! { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(99, 0, 0B, 0B, 0B, 0, 
0B, 3, interopobjs\.\[0-9\]+," "gimple" } }
+! { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(99, 3, 
&interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, &pref_type\.\[0-9\]+, " 
"gimple" } }
+! { dg-final { scan-tree-dump "__builtin_GOMP_interop \\(99, 0, 0B, 0B, 0B, 0, 
0B, 3, &interopobjs\.\[0-9\]+," "gimple" } }
 ! { dg-final { scan-tree-dump "g \\(&interop\.\[0-9\]+, interop\.\[0-9\]+, 
&interop\.\[0-9\]+\\)" "gimple" } }
diff --git a/libgomp/testsuite/libgomp.c/append-args-fr-1.c 
b/libgomp/testsuite/libgomp.c/append-args-fr-1.c
new file mode 100644
index 000000000000..2fd7edad9f6a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/append-args-fr-1.c
@@ -0,0 +1,232 @@
+/* { dg-do run } */
+
+#include "append-args-fr.h"
+
+enum { host_device, nvptx_device, gcn_device } used_device_type, 
used_device_type2;
+static int used_device_num, used_device_num2;
+static omp_interop_fr_t expected_fr, expected_fr2;
+static _Bool is_targetsync, is_targetsync2;
+
+void
+check_interop (omp_interop_t obj)
+{
+  if (used_device_type == host_device)
+    check_host (obj);
+  else if (used_device_type == nvptx_device)
+    check_nvptx (obj, used_device_num, expected_fr, is_targetsync);
+  else if (used_device_type == gcn_device)
+    check_gcn (obj, used_device_num, expected_fr, is_targetsync);
+  else
+    __builtin_unreachable ();
+
+  #pragma omp interop use(obj)
+}
+
+void
+check_interop2 (omp_interop_t obj, omp_interop_t obj2)
+{
+  check_interop (obj);
+
+  #pragma omp interop use(obj2)
+
+  if (used_device_type2 == host_device)
+    check_host (obj2);
+  else if (used_device_type2 == nvptx_device)
+    check_nvptx (obj2, used_device_num2, expected_fr2, is_targetsync2);
+  else if (used_device_type2 == gcn_device)
+    check_gcn (obj2, used_device_num2, expected_fr2, is_targetsync2);
+  else
+    __builtin_unreachable ();
+}
+
+
+/* Check no args + one interop arg - and no prefer_type.  */
+
+int f0_1_tg_ (omp_interop_t obj) { check_interop (obj); return 4242; }
+#pragma omp declare variant(f0_1_tg_)     match(construct={dispatch}) 
append_args(interop(target))
+int f0_1_tg () { assert (false); return 42; }
+
+void f0_1_tgsy_ (omp_interop_t obj) { check_interop (obj); }
+#pragma omp declare variant(f0_1_tgsy_)   match(construct={dispatch}) 
append_args(interop(targetsync))
+void f0_1_tgsy () { assert (false); }
+
+int f0_1_tgtgsy_ (omp_interop_t obj) { check_interop (obj); return 3333; }
+#pragma omp declare variant(f0_1_tgtgsy_) match(construct={dispatch}) 
append_args(interop(targetsync,target))
+int f0_1_tgtgsy () { assert (false); return 33; }
+
+
+/* And with PREFER_TYPE.  */
+
+// nv: cuda, gcn: -, -, hip
+void f0_1_tgsy_c_cd_hi_hs_ (omp_interop_t obj) { check_interop (obj); }
+#pragma omp declare variant(f0_1_tgsy_c_cd_hi_hs_)   
match(construct={dispatch}) \
+            append_args(interop(targetsync, prefer_type("cuda","cuda_driver", 
"hip", "hsa")))
+void f0_1_tgsy_c_cd_hi_hs () { assert (false); }
+
+// nv: -, cuda_driver, gcn: hsa
+void f0_1_tgsy_hs_cd_c_hi_ (omp_interop_t obj) { check_interop (obj); }
+#pragma omp declare variant(f0_1_tgsy_hs_cd_c_hi_)   
match(construct={dispatch}) \
+            append_args(interop(targetsync, prefer_type({attr("ompx_foo")}, 
{fr("hsa")}, {attr("ompx_bar"), fr("cuda_driver"), 
attr("ompx_foobar")},{fr("cuda")}, {fr("hip")})))
+void f0_1_tgsy_hs_cd_c_hi () { assert (false); }
+
+// nv: -, hip, gcn: hsa
+void f0_1_tgsy_hs_hi_cd_c_ (omp_interop_t obj) { check_interop (obj); }
+#pragma omp declare variant(f0_1_tgsy_hs_hi_cd_c_)   
match(construct={dispatch}) \
+            append_args(interop(targetsync, prefer_type("hsa", "hip", 
"cuda_driver", "cuda")))
+void f0_1_tgsy_hs_hi_cd_c () { assert (false); }
+
+
+void
+check_f0 ()
+{
+  if (used_device_type == nvptx_device)
+    expected_fr = omp_ifr_cuda;
+  else if (used_device_type == gcn_device)
+    expected_fr = omp_ifr_hip;
+  else  /* host; variable shall not be accessed  */
+    expected_fr = omp_ifr_level_zero;
+
+  int i;
+  if (used_device_num == DEFAULT_DEVICE)
+    {
+      is_targetsync = 0;
+      #pragma omp dispatch
+        i = f0_1_tg ();
+      assert (i == 4242);
+
+      is_targetsync = 1;
+      #pragma omp dispatch
+        f0_1_tgsy ();
+
+      #pragma omp dispatch
+        i = f0_1_tgtgsy ();
+      assert (i == 3333);
+
+
+      if (used_device_type == nvptx_device)
+       expected_fr = omp_ifr_cuda;
+      else if (used_device_type == gcn_device)
+       expected_fr = omp_ifr_hip;
+      #pragma omp dispatch
+        f0_1_tgsy_c_cd_hi_hs ();
+
+      if (used_device_type == nvptx_device)
+       expected_fr = omp_ifr_cuda_driver;
+      else if (used_device_type == gcn_device)
+       expected_fr = omp_ifr_hsa;
+      #pragma omp dispatch
+       f0_1_tgsy_hs_cd_c_hi ();
+  
+      if (used_device_type == nvptx_device)
+       expected_fr = omp_ifr_hip;
+      else if (used_device_type == gcn_device)
+       expected_fr = omp_ifr_hsa;
+      #pragma omp dispatch
+       f0_1_tgsy_hs_hi_cd_c ();
+    }
+  else
+    {
+      is_targetsync = 0;
+      #pragma omp dispatch device(used_device_num)
+        i = f0_1_tg ();
+      assert (i == 4242);
+
+      is_targetsync = 1;
+      #pragma omp dispatch device(used_device_num)
+        f0_1_tgsy ();
+
+      #pragma omp dispatch device(used_device_num)
+        i = f0_1_tgtgsy ();
+      assert (i == 3333);
+
+
+      if (used_device_type == nvptx_device)
+       expected_fr = omp_ifr_cuda;
+      else if (used_device_type == gcn_device)
+       expected_fr = omp_ifr_hip;
+      #pragma omp dispatch device(used_device_num)
+        f0_1_tgsy_c_cd_hi_hs ();
+
+      if (used_device_type == nvptx_device)
+       expected_fr = omp_ifr_cuda_driver;
+      else if (used_device_type == gcn_device)
+       expected_fr = omp_ifr_hsa;
+      #pragma omp dispatch device(used_device_num)
+       f0_1_tgsy_hs_cd_c_hi ();
+  
+      if (used_device_type == nvptx_device)
+       expected_fr = omp_ifr_hip;
+      else if (used_device_type == gcn_device)
+       expected_fr = omp_ifr_hsa;
+      #pragma omp dispatch device(used_device_num)
+       f0_1_tgsy_hs_hi_cd_c ();
+    }
+}
+
+
+
+void
+do_check (int dev)
+{
+  int num_dev = omp_get_num_devices ();
+  const char *dev_type;
+  if (dev != DEFAULT_DEVICE)
+    omp_set_default_device (dev);
+  int is_nvptx = on_device_arch_nvptx ();
+  int is_gcn = on_device_arch_gcn ();
+  int is_host;
+ 
+  if (dev != DEFAULT_DEVICE)
+    is_host = dev == -1 || dev == num_dev;
+  else
+    {
+      int def_dev = omp_get_default_device ();
+      is_host = def_dev == -1 || def_dev == num_dev;
+    }
+
+  assert (is_nvptx + is_gcn + is_host == 1);
+
+  if (num_dev > 0 && dev != DEFAULT_DEVICE)
+    {
+      if (is_host)
+       omp_set_default_device (0);
+      else
+       omp_set_default_device (-1);
+    }
+
+  used_device_num = dev;
+  if (is_host)
+    {
+      dev_type = "host";
+      used_device_type = host_device;
+    }
+  else if (is_nvptx)
+    {
+      dev_type = "nvptx";
+      used_device_type = nvptx_device;
+    }
+  else if (is_gcn)
+    {
+      dev_type = "gcn";
+      used_device_type = gcn_device;
+    }
+
+  printf ("Running on the %s device (%d)\n", dev_type, dev);
+  check_f0 ();
+}
+
+
+
+int
+main ()
+{
+  do_check (DEFAULT_DEVICE);
+  int ndev = omp_get_num_devices ();
+  for (int dev = -1; dev < ndev; dev++)
+    do_check (dev);
+  for (int dev = -1; dev < ndev; dev++)
+    {
+      omp_set_default_device (dev);
+      do_check (DEFAULT_DEVICE);
+    }
+}
diff --git a/libgomp/testsuite/libgomp.c/append-args-fr.h 
b/libgomp/testsuite/libgomp.c/append-args-fr.h
new file mode 100644
index 000000000000..9f6ca04bbe9e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/append-args-fr.h
@@ -0,0 +1,305 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <omp.h>
+#include "../libgomp.c-c++-common/on_device_arch.h"
+
+/* Provides:  */
+
+#define DEFAULT_DEVICE -99
+
+void check_host (omp_interop_t obj);
+void check_nvptx (omp_interop_t obj, int dev, omp_interop_fr_t expected_fr, 
_Bool is_targetsync);
+void check_gcn (omp_interop_t obj, int dev, omp_interop_fr_t expected_fr, 
_Bool is_targetsync);
+
+
+/* The following assumes that when a nvptx device is available,
+   cuda/cuda_driver/hip are supported.
+   And that likewise when a gcn device is available that the
+   plugin also can not only the HSA but also the HIP library
+   such that hsa/hip are supported.
+   For the host, omp_interop_none is expected.
+
+   Otherwise, it only does some basic tests without checking
+   that the returned result really makes sense.  */
+
+void check_type (omp_interop_t obj)
+{
+  const char *type;
+
+  type = omp_get_interop_type_desc (obj, omp_ipr_fr_id);
+  if (obj != omp_interop_none)
+    assert (strcmp (type, "omp_interop_t") == 0);
+  else
+    assert (type == NULL);
+
+  type = omp_get_interop_type_desc (obj, omp_ipr_fr_name);
+  if (obj != omp_interop_none)
+    assert (strcmp (type, "const char *") == 0);
+  else
+    assert (type == NULL);
+
+  type = omp_get_interop_type_desc (obj, omp_ipr_vendor);
+  if (obj != omp_interop_none)
+    assert (strcmp (type, "int") == 0);
+  else
+    assert (type == NULL);
+
+  type = omp_get_interop_type_desc (obj, omp_ipr_vendor_name);
+  if (obj != omp_interop_none)
+    assert (strcmp (type, "const char *") == 0);
+  else
+    assert (type == NULL);
+
+  type = omp_get_interop_type_desc (obj, omp_ipr_device_num);
+  if (obj != omp_interop_none)
+    assert (strcmp (type, "int") == 0);
+  else
+    assert (type == NULL);
+
+  if (obj != omp_interop_none)
+    return;
+  assert (omp_get_interop_type_desc (obj, omp_ipr_platform) == NULL);
+  assert (omp_get_interop_type_desc (obj, omp_ipr_device) == NULL);
+  assert (omp_get_interop_type_desc (obj, omp_ipr_device_context) == NULL);
+  assert (omp_get_interop_type_desc (obj, omp_ipr_targetsync) == NULL);
+}
+
+
+void
+check_host (omp_interop_t obj)
+{
+  assert (obj == omp_interop_none);
+  check_type (obj);
+}
+
+
+void
+check_nvptx (omp_interop_t obj, int dev, omp_interop_fr_t expected_fr, _Bool 
is_targetsync)
+{
+  assert (obj != omp_interop_none && obj != (omp_interop_t) -1L);
+
+  omp_interop_rc_t ret_code = omp_irc_no_value;
+  omp_interop_fr_t fr = (omp_interop_fr_t) omp_get_interop_int (obj, 
omp_ipr_fr_id, &ret_code);
+
+  assert (ret_code == omp_irc_success);
+  assert (fr == expected_fr);
+
+  ret_code = omp_irc_no_value;
+  const char *fr_name = omp_get_interop_str (obj, omp_ipr_fr_name, &ret_code);
+
+  assert (ret_code == omp_irc_success);
+  if (fr == omp_ifr_cuda)
+    assert (strcmp (fr_name, "cuda") == 0);
+  else if (fr == omp_ifr_cuda_driver)
+    assert (strcmp (fr_name, "cuda_driver") == 0);
+  else if (fr == omp_ifr_hip)
+    assert (strcmp (fr_name, "hip") == 0);
+  else
+    assert (0);
+
+  ret_code = omp_irc_no_value;
+  int vendor = (int) omp_get_interop_int (obj, omp_ipr_vendor, &ret_code);
+  assert (ret_code == omp_irc_success);
+  assert (vendor == 11);  /* Nvidia */
+
+  ret_code = omp_irc_no_value;
+  const char *vendor_name = omp_get_interop_str (obj, omp_ipr_vendor_name, 
&ret_code);
+  assert (ret_code == omp_irc_success);
+  assert (strcmp (vendor_name, "nvidia") == 0);
+
+  ret_code = omp_irc_no_value;
+  int dev_num = (int) omp_get_interop_int (obj, omp_ipr_device_num, &ret_code);
+  assert (ret_code == omp_irc_success);
+  if (dev == DEFAULT_DEVICE)
+    assert (dev_num == omp_get_default_device ());
+  else
+    assert (dev_num == dev);
+
+  /* Platform: N/A.  */
+  ret_code = omp_irc_success;
+  (void) omp_get_interop_int (obj, omp_ipr_platform, &ret_code);
+  assert (ret_code == omp_irc_no_value);
+  ret_code = omp_irc_success;
+  (void) omp_get_interop_ptr (obj, omp_ipr_platform, &ret_code);
+  assert (ret_code == omp_irc_no_value);
+  ret_code = omp_irc_success;
+  (void) omp_get_interop_str (obj, omp_ipr_platform, &ret_code);
+  assert (ret_code == omp_irc_no_value);
+
+  /* Device: int / CUdevice / hipDevice_t -- all internally an 'int'.  */
+  ret_code = omp_irc_no_value;
+  int fr_device = (int) omp_get_interop_int (obj, omp_ipr_device, &ret_code);
+
+  /* CUDA also starts from 0 and goes to < n with cudaGetDeviceCount(&cn).  */
+  assert (ret_code == omp_irc_success);
+  assert (fr_device >= 0 && fr_device < omp_get_num_devices ());
+
+  /* Device context: N/A / CUcontext / hipCtx_t -- a pointer.  */
+  ret_code = omp_irc_out_of_range;
+  void *ctx = omp_get_interop_ptr (obj, omp_ipr_device_context, &ret_code);
+
+  if (fr == omp_ifr_cuda)
+    {
+      assert (ret_code == omp_irc_no_value);
+      assert (ctx == NULL);
+    }
+  else
+    {
+      assert (ret_code == omp_irc_success);
+      assert (ctx != NULL);
+    }
+
+  /* Stream/targetsync: cudaStream_t / CUstream / hipStream_t -- a pointer.  */
+  ret_code = omp_irc_out_of_range;
+  void *stream = omp_get_interop_ptr (obj, omp_ipr_targetsync, &ret_code);
+
+  if (is_targetsync)  /* no targetsync */
+    {
+      assert (ret_code == omp_irc_success);
+      assert (stream != NULL);
+    }
+  else
+    {
+      assert (ret_code == omp_irc_no_value);
+      assert (stream == NULL);
+    }
+
+  check_type (obj);
+  if (fr == omp_ifr_cuda)
+    {
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_platform), 
"N/A") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device), "int") 
== 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device_context), 
"N/A") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_targetsync), 
"cudaStream_t") == 0);
+    }
+  else if (fr == omp_ifr_cuda_driver)
+    {
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_platform), 
"N/A") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device), 
"CUdevice") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device_context), 
"CUcontext") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_targetsync), 
"CUstream") == 0);
+    }
+  else
+    {
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_platform), 
"N/A") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device), 
"hipDevice_t") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device_context), 
"hipCtx_t") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_targetsync), 
"hipStream_t") == 0);
+    }
+}
+
+
+void
+check_gcn (omp_interop_t obj, int dev, omp_interop_fr_t expected_fr, _Bool 
is_targetsync)
+{
+  assert (obj != omp_interop_none && obj != (omp_interop_t) -1L);
+
+  omp_interop_rc_t ret_code = omp_irc_no_value;
+  omp_interop_fr_t fr = (omp_interop_fr_t) omp_get_interop_int (obj, 
omp_ipr_fr_id, &ret_code);
+
+  assert (ret_code == omp_irc_success);
+  assert (fr == expected_fr);
+
+  ret_code = omp_irc_no_value;
+  const char *fr_name = omp_get_interop_str (obj, omp_ipr_fr_name, &ret_code);
+
+   assert (ret_code == omp_irc_success);
+  if (fr == omp_ifr_hip)
+    assert (strcmp (fr_name, "hip") == 0);
+  else if (fr == omp_ifr_hsa)
+    assert (strcmp (fr_name, "hsa") == 0);
+  else
+    assert (0);
+
+  ret_code = omp_irc_no_value;
+  int vendor = (int) omp_get_interop_int (obj, omp_ipr_vendor, &ret_code);
+  assert (ret_code == omp_irc_success);
+  assert (vendor == 1);  /* Amd */
+
+  ret_code = omp_irc_no_value;
+  const char *vendor_name = omp_get_interop_str (obj, omp_ipr_vendor_name, 
&ret_code);
+  assert (ret_code == omp_irc_success);
+  assert (strcmp (vendor_name, "amd") == 0);
+
+  ret_code = omp_irc_no_value;
+  int dev_num = (int) omp_get_interop_int (obj, omp_ipr_device_num, &ret_code);
+  assert (ret_code == omp_irc_success);
+  if (dev == DEFAULT_DEVICE)
+    assert (dev_num == omp_get_default_device ());
+  else
+    assert (dev_num == dev);
+
+  /* Platform: N/A.  */
+  ret_code = omp_irc_success;
+  (void) omp_get_interop_int (obj, omp_ipr_platform, &ret_code);
+  assert (ret_code == omp_irc_no_value);
+  ret_code = omp_irc_success;
+  (void) omp_get_interop_ptr (obj, omp_ipr_platform, &ret_code);
+  assert (ret_code == omp_irc_no_value);
+  ret_code = omp_irc_success;
+  (void) omp_get_interop_str (obj, omp_ipr_platform, &ret_code);
+  assert (ret_code == omp_irc_no_value);
+
+  /* Device: hipDevice_t / hsa_agent_t* -- hip is internally an 'int'.  */
+  ret_code = omp_irc_no_value;
+  if (fr == omp_ifr_hip)
+    {
+      /* HIP also starts from 0 and goes to < n as with 
cudaGetDeviceCount(&cn).  */
+      int fr_device = (int) omp_get_interop_int (obj, omp_ipr_device, 
&ret_code);
+      assert (ret_code == omp_irc_success);
+      assert (fr_device >= 0 && fr_device < omp_get_num_devices ());
+    }
+  else
+    {
+      void *agent = omp_get_interop_ptr (obj, omp_ipr_device, &ret_code);
+      assert (ret_code == omp_irc_success);
+      assert (agent != NULL);
+    }
+
+  /* Device context: hipCtx_t / N/A -- a pointer.  */
+  ret_code = omp_irc_out_of_range;
+  void *ctx = omp_get_interop_ptr (obj, omp_ipr_device_context, &ret_code);
+  if (fr == omp_ifr_hip)
+    {
+      assert (ret_code == omp_irc_success);
+      assert (ctx != NULL);
+    }
+  else
+    {
+      assert (ret_code == omp_irc_no_value);
+      assert (ctx == NULL);
+    }
+
+  /* Stream/targetsync: cudaStream_t / CUstream / hipStream_t -- a pointer.  */
+  ret_code = omp_irc_out_of_range;
+  void *stream = omp_get_interop_ptr (obj, omp_ipr_targetsync, &ret_code);
+
+  if (is_targetsync)
+    {
+      assert (ret_code == omp_irc_success);
+      assert (stream != NULL);
+    }
+  else
+    {
+      assert (ret_code == omp_irc_no_value);
+      assert (stream == NULL);
+    }
+
+  check_type (obj);
+  if (fr == omp_ifr_hip)
+    {
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_platform), 
"N/A") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device), 
"hipDevice_t") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device_context), 
"hipCtx_t") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_targetsync), 
"hipStream_t") == 0);
+    }
+  else
+    {
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_platform), 
"N/A") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device), 
"hsa_agent_t *") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_device_context), 
"N/A") == 0);
+      assert (strcmp (omp_get_interop_type_desc (obj, omp_ipr_targetsync), 
"hsa_queue_t *") == 0);
+    }
+}

Reply via email to