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.
This commit is contained in:
Tobias Burnus 2025-04-08 13:47:53 +02:00
parent d034c78c7b
commit 0f77d88fdf
6 changed files with 563 additions and 22 deletions

View file

@ -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))

View file

@ -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" } } */

View file

@ -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" } } */

View file

@ -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" } }

View file

@ -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);
}
}

View file

@ -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);
}
}