[llvm] [OpenMP] Add tests for mapping of chained 'containing' structs (PR #156703)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 3 08:52:45 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-offload
Author: Julian Brown (jtb20)
<details>
<summary>Changes</summary>
This PR adds several new tests for mapping of chained structures, i.e. those resembling:
```
#pragma omp target map(tofrom: a->b->c)
```
These are currently XFAILed, although the first two tests actually work with unified memory -- I'm not sure if it's possible to easily improve the condition on the XFAILs in question to make them more accurate.
These cases are all fixed by the WIP PR https://github.com/llvm/llvm-project/pull/153683.
---
Full diff: https://github.com/llvm/llvm-project/pull/156703.diff
3 Files Affected:
- (added) offload/test/mapping/chained_containing_structs_1.cc (+58)
- (added) offload/test/mapping/chained_containing_structs_2.cc (+76)
- (added) offload/test/mapping/chained_containing_structs_3.cc (+222)
``````````diff
diff --git a/offload/test/mapping/chained_containing_structs_1.cc b/offload/test/mapping/chained_containing_structs_1.cc
new file mode 100644
index 0000000000000..9ca148a7823b0
--- /dev/null
+++ b/offload/test/mapping/chained_containing_structs_1.cc
@@ -0,0 +1,58 @@
+// RUN: %libomptarget-compilexx-and-run-generic
+// XFAIL: *
+
+#include <cstdlib>
+#include <cstdio>
+#include <cassert>
+
+struct S {
+ int a;
+ int b;
+ int c;
+};
+
+struct T {
+ S *s0;
+ S *s1;
+ S *s2;
+};
+
+int main() {
+ T *v = (T *) malloc (sizeof(T));
+ v->s0 = (S *) malloc (sizeof(S));
+ v->s1 = (S *) malloc (sizeof(S));
+ v->s2 = (S *) malloc (sizeof(S));
+ v->s0->a = 10;
+ v->s0->b = 10;
+ v->s0->c = 10;
+ v->s1->a = 20;
+ v->s1->b = 20;
+ v->s1->c = 20;
+ v->s2->a = 30;
+ v->s2->b = 30;
+ v->s2->c = 30;
+
+#pragma omp target map(to: v[:1]) map(tofrom: v->s1->b, v->s1->c, v->s2->b)
+ {
+ v->s1->b += 3;
+ v->s1->c += 5;
+ v->s2->b += 7;
+ }
+
+ assert (v->s0->a == 10);
+ assert (v->s0->b == 10);
+ assert (v->s0->c == 10);
+ assert (v->s1->a == 20);
+ assert (v->s1->b == 23);
+ assert (v->s1->c == 25);
+ assert (v->s2->a == 30);
+ assert (v->s2->b == 37);
+ assert (v->s2->c == 30);
+
+ free(v->s0);
+ free(v->s1);
+ free(v->s2);
+ free(v);
+
+ return 0;
+}
diff --git a/offload/test/mapping/chained_containing_structs_2.cc b/offload/test/mapping/chained_containing_structs_2.cc
new file mode 100644
index 0000000000000..22660a4fb8c3f
--- /dev/null
+++ b/offload/test/mapping/chained_containing_structs_2.cc
@@ -0,0 +1,76 @@
+// RUN: %libomptarget-compilexx-and-run-generic
+// XFAIL: *
+
+#include <cstdlib>
+#include <cstdio>
+#include <cassert>
+
+struct R {
+ int d;
+ int e;
+ int f;
+};
+
+struct S {
+ R *r0;
+ R *r1;
+ R *r2;
+};
+
+struct T {
+ S *s0;
+ S *s1;
+ S *s2;
+};
+
+int main() {
+ T *v = (T *) malloc (sizeof(T));
+
+ v->s0 = (S *) malloc (sizeof(S));
+ v->s1 = (S *) malloc (sizeof(S));
+ v->s2 = (S *) malloc (sizeof(S));
+
+ v->s0->r0 = (R *) calloc (1, sizeof(R));
+ v->s0->r1 = (R *) calloc (1, sizeof(R));
+ v->s0->r2 = (R *) calloc (1, sizeof(R));
+
+ v->s1->r0 = (R *) calloc (1, sizeof(R));
+ v->s1->r1 = (R *) calloc (1, sizeof(R));
+ v->s1->r2 = (R *) calloc (1, sizeof(R));
+
+ v->s2->r0 = (R *) calloc (1, sizeof(R));
+ v->s2->r1 = (R *) calloc (1, sizeof(R));
+ v->s2->r2 = (R *) calloc (1, sizeof(R));
+
+ #pragma omp target map(to: v->s1, v->s2, *v->s1, v->s1->r1, *v->s2, v->s2->r0) \
+ map(tofrom: v->s1->r1->d, v->s1->r1->e, v->s1->r2->d, v->s1->r2->f, v->s2->r0->e)
+ {
+ v->s1->r1->d += 3;
+ v->s1->r1->e += 5;
+ v->s1->r2->d += 7;
+ v->s1->r2->f += 9;
+ v->s2->r0->e += 11;
+ }
+
+ assert(v->s1->r1->d == 3);
+ assert(v->s1->r1->e == 5);
+ assert(v->s1->r2->d == 7);
+ assert(v->s1->r2->f == 9);
+ assert(v->s2->r0->e == 11);
+
+ free(v->s0->r0);
+ free(v->s0->r1);
+ free(v->s0->r2);
+ free(v->s1->r0);
+ free(v->s1->r1);
+ free(v->s1->r2);
+ free(v->s2->r0);
+ free(v->s2->r1);
+ free(v->s2->r2);
+ free(v->s0);
+ free(v->s1);
+ free(v->s2);
+ free(v);
+
+ return 0;
+}
diff --git a/offload/test/mapping/chained_containing_structs_3.cc b/offload/test/mapping/chained_containing_structs_3.cc
new file mode 100644
index 0000000000000..406da074d9361
--- /dev/null
+++ b/offload/test/mapping/chained_containing_structs_3.cc
@@ -0,0 +1,222 @@
+// RUN: %libomptarget-compilexx-and-run-generic
+// XFAIL: *
+
+#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;
+}
+ assert(r.d == 1);
+ assert(r.e == 2);
+ assert(r.f == 3);
+
+#pragma omp target map(tofrom: rp[:1]) map(tofrom: rp->e)
+{
+ rp->d++;
+ rp->e += 2;
+ rp->f += 3;
+}
+
+ assert(rp->d == 1);
+ assert(rp->e == 2);
+ assert(rp->f == 3);
+
+ int v;
+ int *orig_addr_v = &v;
+ bool separate_memory_space;
+
+#pragma omp target data use_device_addr(v)
+ {
+ void *mapped_ptr_v =
+ omp_get_mapped_ptr(orig_addr_v, omp_get_default_device());
+ separate_memory_space = mapped_ptr_v != orig_addr_v;
+ }
+
+#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;
+}
+
+ if (separate_memory_space) {
+ assert(s.b == 0);
+ assert(s.sub.r.d == 0);
+ assert(s.sub.r.e == 3);
+ assert(s.sub.r.f == 0);
+ } else {
+ assert(s.b == 1);
+ assert(s.sub.r.d == 2);
+ assert(s.sub.r.e == 3);
+ assert(s.sub.r.f == 4);
+ }
+
+#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;
+}
+
+ if (separate_memory_space) {
+ assert(s.b == 0);
+ assert(s.sub.rp->d == 0);
+ assert(s.sub.rp->e == 3);
+ assert(s.sub.rp->f == 0);
+ } else {
+ assert(s.b == 2);
+ assert(s.sub.rp->d == 2);
+ assert(s.sub.rp->e == 3);
+ assert(s.sub.rp->f == 4);
+ }
+
+#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;
+}
+
+ if (separate_memory_space) {
+ assert(sp->b == 0);
+ assert(sp->sub.r.d == 0);
+ assert(sp->sub.r.e == 3);
+ assert(sp->sub.r.f == 0);
+ } else {
+ assert(sp->b == 1);
+ assert(sp->sub.r.d == 2);
+ assert(sp->sub.r.e == 3);
+ assert(sp->sub.r.f == 4);
+ }
+
+#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;
+}
+
+ if (separate_memory_space) {
+ assert(sp->b == 0);
+ assert(sp->sub.rp->d == 0);
+ assert(sp->sub.rp->e == 3);
+ assert(sp->sub.rp->f == 0);
+ } else {
+ assert(sp->b == 2);
+ assert(sp->sub.rp->d == 2);
+ assert(sp->sub.rp->e == 3);
+ assert(sp->sub.rp->f == 4);
+ }
+
+#pragma omp target map(tofrom: t) map(tofrom: t.ptr[2:1])
+{
+ t.a++;
+ t.ptr[2]+=2;
+ t.b+=3;
+}
+
+ assert(t.a == 1);
+ assert(t.ptr[2] == 2);
+ assert(t.b == 3);
+
+#pragma omp target map(tofrom: t) map(tofrom: t.a)
+{
+ t.b++;
+}
+
+ assert(t.b == 4);
+
+#pragma omp target map(tofrom: t) map(tofrom: t.ptr[2:1], t.a)
+{
+ t.a++;
+ t.ptr[2]+=2;
+ t.b+=3;
+}
+
+ assert(t.a == 2);
+ assert(t.ptr[2] == 4);
+ assert(t.b == 7);
+
+#pragma omp target map(tofrom: t) map(tofrom: t.ptr[2:1], t.a)
+{
+ /* Empty */
+}
+
+ assert(t.a == 2);
+ assert(t.ptr[2] == 4);
+ assert(t.b == 7);
+
+ delete s.sub.rp;
+ delete sp->sub.rp;
+
+ delete[] t.ptr;
+ delete[] tp->ptr;
+
+ delete rp;
+ delete sp;
+ delete tp;
+
+ return 0;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/156703
More information about the llvm-commits
mailing list