| // RUN: %libomptarget-compilexx-run-and-check-generic |
| |
| #include <cstdlib> |
| #include <cstdio> |
| #include <cassert> |
| #include <cstring> |
| |
| #include <omp.h> |
| |
| struct R { |
| int d; |
| int e; |
| int f; |
| }; |
| |
| struct S { |
| int a; |
| int b; |
| struct { |
| int c; |
| R r; |
| R *rp; |
| } sub; |
| int g; |
| }; |
| |
| struct T { |
| int a; |
| int *ptr; |
| int b; |
| }; |
| |
| int main() { |
| R r; |
| R *rp = new R; |
| S s; |
| S *sp = new S; |
| T t; |
| T *tp = new T; |
| |
| memset(&r, 0, sizeof(R)); |
| memset(rp, 0, sizeof(R)); |
| memset(&s, 0, sizeof(S)); |
| memset(sp, 0, sizeof(S)); |
| memset(&t, 0, sizeof(T)); |
| memset(tp, 0, sizeof(T)); |
| |
| s.sub.rp = new R; |
| sp->sub.rp = new R; |
| |
| memset(s.sub.rp, 0, sizeof(R)); |
| memset(sp->sub.rp, 0, sizeof(R)); |
| |
| t.ptr = new int[10]; |
| tp->ptr = new int[10]; |
| |
| memset(t.ptr, 0, sizeof(int)*10); |
| memset(tp->ptr, 0, sizeof(int)*10); |
| |
| #pragma omp target map(tofrom: r) map(tofrom: r.e) |
| { |
| r.d++; |
| r.e += 2; |
| r.f += 3; |
| } |
| printf ("%d\n", r.d); // CHECK: 1 |
| printf ("%d\n", r.e); // CHECK-NEXT: 2 |
| printf ("%d\n", r.f); // CHECK-NEXT: 3 |
| |
| #pragma omp target map(tofrom: rp[:1]) map(tofrom: rp->e) |
| { |
| rp->d++; |
| rp->e += 2; |
| rp->f += 3; |
| } |
| |
| printf ("%d\n", rp->d); // CHECK-NEXT: 1 |
| printf ("%d\n", rp->e); // CHECK-NEXT: 2 |
| printf ("%d\n", rp->f); // CHECK-NEXT: 3 |
| |
| int v; |
| int *orig_addr_v = &v; |
| bool separate_memory_space; |
| |
| #pragma omp target data map(v) |
| { |
| void *mapped_ptr_v = |
| omp_get_mapped_ptr(orig_addr_v, omp_get_default_device()); |
| separate_memory_space = mapped_ptr_v != (void*) orig_addr_v; |
| } |
| |
| const char *mapping_flavour = separate_memory_space ? "separate" : "unified"; |
| |
| #pragma omp target map(to: s) map(tofrom: s.sub.r.e) |
| { |
| s.b++; |
| s.sub.r.d+=2; |
| s.sub.r.e+=3; |
| s.sub.r.f+=4; |
| } |
| |
| printf ("%d/%s\n", s.b, mapping_flavour); |
| printf ("%d/%s\n", s.sub.r.d, mapping_flavour); |
| printf ("%d/%s\n", s.sub.r.e, mapping_flavour); |
| printf ("%d/%s\n", s.sub.r.f, mapping_flavour); |
| |
| // CHECK: {{0/separate|1/unified}} |
| // CHECK-NEXT: {{0/separate|2/unified}} |
| // CHECK-NEXT: 3 |
| // CHECK-NEXT: {{0/separate|4/unified}} |
| |
| #pragma omp target map(to: s, s.b) map(to: s.sub.rp[:1]) map(tofrom: s.sub.rp->e) |
| { |
| s.b++; |
| s.sub.rp->d+=2; |
| s.sub.rp->e+=3; |
| s.sub.rp->f+=4; |
| } |
| |
| printf ("%d/%s\n", s.b, mapping_flavour); |
| printf ("%d/%s\n", s.sub.rp->d, mapping_flavour); |
| printf ("%d/%s\n", s.sub.rp->e, mapping_flavour); |
| printf ("%d/%s\n", s.sub.rp->f, mapping_flavour); |
| |
| // CHECK-NEXT: {{0/separate|2/unified}} |
| // CHECK-NEXT: {{0/separate|2/unified}} |
| // CHECK-NEXT: 3 |
| // CHECK-NEXT: {{0/separate|4/unified}} |
| |
| #pragma omp target map(to: sp[:1]) map(tofrom: sp->sub.r.e) |
| { |
| sp->b++; |
| sp->sub.r.d+=2; |
| sp->sub.r.e+=3; |
| sp->sub.r.f+=4; |
| } |
| |
| printf ("%d/%s\n", sp->b, mapping_flavour); |
| printf ("%d/%s\n", sp->sub.r.d, mapping_flavour); |
| printf ("%d/%s\n", sp->sub.r.e, mapping_flavour); |
| printf ("%d/%s\n", sp->sub.r.f, mapping_flavour); |
| |
| // CHECK-NEXT: {{0/separate|1/unified}} |
| // CHECK-NEXT: {{0/separate|2/unified}} |
| // CHECK-NEXT: 3 |
| // CHECK-NEXT: {{0/separate|4/unified}} |
| |
| #pragma omp target map(to: sp[:1]) map(to: sp->sub.rp[:1]) map(tofrom: sp->sub.rp->e) |
| { |
| sp->b++; |
| sp->sub.rp->d+=2; |
| sp->sub.rp->e+=3; |
| sp->sub.rp->f+=4; |
| } |
| |
| printf ("%d/%s\n", sp->b, mapping_flavour); |
| printf ("%d/%s\n", sp->sub.rp->d, mapping_flavour); |
| printf ("%d/%s\n", sp->sub.rp->e, mapping_flavour); |
| printf ("%d/%s\n", sp->sub.rp->f, mapping_flavour); |
| |
| // CHECK-NEXT: {{0/separate|2/unified}} |
| // CHECK-NEXT: {{0/separate|2/unified}} |
| // CHECK-NEXT: 3 |
| // CHECK-NEXT: {{0/separate|4/unified}} |
| |
| #pragma omp target map(tofrom: t) map(tofrom: t.ptr[2:1]) |
| { |
| t.a++; |
| t.ptr[2]+=2; |
| t.b+=3; |
| } |
| |
| printf ("%d\n", t.a); // CHECK-NEXT: 1 |
| printf ("%d\n", t.ptr[2]); // CHECK-NEXT: 2 |
| printf ("%d\n", t.b); // CHECK-NEXT: 3 |
| |
| #pragma omp target map(tofrom: t) map(tofrom: t.a) |
| { |
| t.b++; |
| } |
| |
| printf ("%d\n", t.b); // CHECK-NEXT: 4 |
| |
| #pragma omp target map(tofrom: t) map(tofrom: t.ptr[2:1], t.a) |
| { |
| t.a++; |
| t.ptr[2]+=2; |
| t.b+=3; |
| } |
| |
| printf ("%d\n", t.a); // CHECK-NEXT: 2 |
| printf ("%d\n", t.ptr[2]); // CHECK-NEXT: 4 |
| printf ("%d\n", t.b); // CHECK-NEXT: 7 |
| |
| #pragma omp target map(tofrom: t) map(tofrom: t.ptr[2:1], t.a) |
| { |
| /* Empty */ |
| } |
| |
| printf ("%d\n", t.a); // CHECK-NEXT: 2 |
| printf ("%d\n", t.ptr[2]); // CHECK-NEXT: 4 |
| printf ("%d\n", t.b); // CHECK-NEXT: 7 |
| |
| delete s.sub.rp; |
| delete sp->sub.rp; |
| |
| delete[] t.ptr; |
| delete[] tp->ptr; |
| |
| delete rp; |
| delete sp; |
| delete tp; |
| |
| return 0; |
| } |