blob: 1064051d412fd3a27cc916ee9079e8fdeaa088b7 [file] [log] [blame]
// RUN: %libomptarget-compile-run-and-check-generic
// UNSUPPORTED: intelgpu
// REQUIRES: gpu
#include <assert.h>
#include <stdio.h>
#define TEST_VAL 5
#pragma omp declare target indirect
int func_a(int x) { return x + 1; }
int func_b(int x) { return x + 2; }
int func_c(int x) { return x + 3; }
int func_d(int x) { return x * 2; }
int func_e(int x) { return x * 3; }
int func_f(int x) { return x * 4; }
#pragma omp end declare target
void test_array_explicit_mapping() {
int (*local_fptr_array[3])(int) = {func_a, func_b, func_c};
int results[3];
int expected[3];
expected[0] = func_a(TEST_VAL);
expected[1] = func_b(TEST_VAL);
expected[2] = func_c(TEST_VAL);
#pragma omp target map(local_fptr_array, local_fptr_array[0 : 3]) \
map(from : results)
{
for (int i = 0; i < 3; i++) {
results[i] = local_fptr_array[i](TEST_VAL);
}
}
for (int i = 0; i < 3; i++) {
assert(results[i] == expected[i] &&
"Error: local array function pointer returned incorrect value on "
"device");
}
// Change function pointers and re-test
local_fptr_array[0] = func_d;
local_fptr_array[1] = func_e;
local_fptr_array[2] = func_f;
expected[0] = func_d(TEST_VAL);
expected[1] = func_e(TEST_VAL);
expected[2] = func_f(TEST_VAL);
#pragma omp target map(local_fptr_array, local_fptr_array[0 : 3]) \
map(from : results)
{
for (int i = 0; i < 3; i++) {
results[i] = local_fptr_array[i](TEST_VAL);
}
}
for (int i = 0; i < 3; i++) {
assert(results[i] == expected[i] &&
"Error: local array function pointer returned incorrect value on "
"device after update");
}
}
struct with_fptr_array {
int buffer;
int (*fptrs[3])(int);
};
void test_struct_containing_array() {
struct with_fptr_array val = {.buffer = 0, .fptrs = {func_a, func_b, func_c}};
int results[3];
int expected[3];
expected[0] = func_a(TEST_VAL);
expected[1] = func_b(TEST_VAL);
expected[2] = func_c(TEST_VAL);
#pragma omp target map(val, val.fptrs[0 : 3]) map(from : results)
{
results[0] = val.fptrs[0](TEST_VAL);
results[1] = val.fptrs[1](TEST_VAL);
results[2] = val.fptrs[2](TEST_VAL);
}
for (int i = 0; i < 3; i++) {
assert(results[i] == expected[i] &&
"Error: struct array function pointer returned incorrect value");
}
// Update and re-test
val.fptrs[0] = func_d;
val.fptrs[1] = func_e;
val.fptrs[2] = func_f;
expected[0] = func_d(TEST_VAL);
expected[1] = func_e(TEST_VAL);
expected[2] = func_f(TEST_VAL);
#pragma omp target map(val, val.fptrs[0 : 3]) map(from : results)
{
results[0] = val.fptrs[0](TEST_VAL);
results[1] = val.fptrs[1](TEST_VAL);
results[2] = val.fptrs[2](TEST_VAL);
}
for (int i = 0; i < 3; i++) {
assert(results[i] == expected[i] &&
"Error: struct array function pointer returned incorrect value "
"after update");
}
}
int main() {
test_array_explicit_mapping();
test_struct_containing_array();
// CHECK: PASS
printf("PASS\n");
return 0;
}