| // RUN: %libomptarget-compilexx-run-and-check-generic |
| // UNSUPPORTED: intelgpu |
| // REQUIRES: gpu |
| |
| #include <assert.h> |
| #include <omp.h> |
| #include <stdio.h> |
| |
| #define TEST_VAL 10 |
| |
| #pragma omp declare target |
| |
| class Base { |
| public: |
| virtual int foo() { return 1; } |
| virtual int bar() { return 2; } |
| virtual int foo_with_arg(int x) { return x; } |
| }; |
| |
| class Derived : public Base { |
| public: |
| virtual int foo() { return 10; } |
| virtual int bar() { return 20; } |
| virtual int foo_with_arg(int x) { return -x; } |
| }; |
| |
| #pragma omp end declare target |
| |
| int test_virtual_implicit_map() { |
| Base base; |
| Derived derived; |
| int result1, result2, result3, result4, result5, result6; |
| |
| // map both base and derived objects up front, since the spec |
| // requires that when first mapping a C++ object that the static |
| // type must match the dynamic type |
| #pragma omp target data map(base, derived) |
| { |
| Base *p1 = &base; |
| Base *p2 = &derived; |
| |
| #pragma omp target map(from : result1, result2, result3, result4, result5, \ |
| result6) |
| { |
| // These calls will fail if Clang does not |
| // translate/attach the vtable pointer in each object |
| result1 = p1->foo(); |
| result2 = p1->bar(); |
| result3 = p2->foo(); |
| result4 = p2->bar(); |
| result5 = base.foo(); |
| result6 = derived.foo(); |
| } |
| } |
| |
| assert(result1 == 1 && "p1->foo() implicit map Failed"); |
| assert(result2 == 2 && "p1->bar() implicit map Failed"); |
| assert(result3 == 10 && "p2->foo() implicit map Failed"); |
| assert(result4 == 20 && "p2->bar() implicit map Failed"); |
| assert(result5 == 1 && "base.foo() implicit map Failed"); |
| assert(result6 == 10 && "derived.foo() implicit map Failed"); |
| return 0; |
| } |
| |
| int test_virtual_explicit_map() { |
| Base base; |
| Derived derived; |
| int result1, result2, result3, result4; |
| |
| // map both base and derived objects up front, since the spec |
| // requires that when first mapping a C++ object that the static |
| // type must match the dynamic type |
| #pragma omp target data map(base, derived) |
| { |
| Base *p1 = &base; |
| Base *p2 = &derived; |
| |
| #pragma omp target map(p1[0 : 0], p2[0 : 0]) \ |
| map(from : result1, result2, result3, result4) |
| { |
| result1 = p1->foo(); |
| result2 = p1->bar(); |
| result3 = p2->foo(); |
| result4 = p2->bar(); |
| } |
| } |
| |
| assert(result1 == 1 && "p1->foo() explicit map Failed"); |
| assert(result2 == 2 && "p1->bar() explicit map Failed"); |
| assert(result3 == 10 && "p2->foo() explicit map Failed"); |
| assert(result4 == 20 && "p2->bar() explicit map Failed"); |
| return 0; |
| } |
| |
| int test_virtual_reference() { |
| Derived ddd; |
| Base cont; |
| Base &bbb = ddd; |
| |
| int b_ret, d_ret, c_ret; |
| |
| #pragma omp target data map(to : ddd, cont) |
| { |
| #pragma omp target map(bbb, ddd, cont) map(from : b_ret, d_ret, c_ret) |
| { |
| b_ret = bbb.foo_with_arg(TEST_VAL); |
| d_ret = ddd.foo_with_arg(TEST_VAL); |
| c_ret = cont.foo_with_arg(TEST_VAL); |
| } |
| } |
| |
| assert(c_ret == TEST_VAL && "Control Base call failed on gpu"); |
| assert(b_ret == -TEST_VAL && "Reference to derived call failed on gpu"); |
| assert(d_ret == -TEST_VAL && "Derived call failed on gpu"); |
| |
| return 0; |
| } |
| |
| int test_virtual_reference_implicit() { |
| Derived ddd; |
| Base cont; |
| Base &bbb = ddd; |
| |
| int b_ret, d_ret, c_ret; |
| |
| #pragma omp target data map(to : ddd, cont) |
| { |
| #pragma omp target map(from : b_ret, d_ret, c_ret) |
| { |
| b_ret = bbb.foo_with_arg(TEST_VAL); |
| d_ret = ddd.foo_with_arg(TEST_VAL); |
| c_ret = cont.foo_with_arg(TEST_VAL); |
| } |
| } |
| |
| assert(c_ret == TEST_VAL && "Control Base call failed on gpu (implicit)"); |
| assert(b_ret == -TEST_VAL && |
| "Reference to derived call failed on gpu (implicit)"); |
| assert(d_ret == -TEST_VAL && "Derived call failed on gpu (implicit)"); |
| |
| return 0; |
| } |
| |
| int main() { |
| test_virtual_implicit_map(); |
| test_virtual_explicit_map(); |
| test_virtual_reference(); |
| test_virtual_reference_implicit(); |
| |
| // CHECK: PASS |
| printf("PASS\n"); |
| return 0; |
| } |