]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Add support for using custom mappers with iterators (C, C++)
authorKwok Cheung Yeung <kcyeung@baylibre.com>
Mon, 13 Jan 2025 13:08:07 +0000 (13:08 +0000)
committerKwok Cheung Yeung <kcyeung@baylibre.com>
Thu, 17 Apr 2025 22:33:34 +0000 (23:33 +0100)
gcc/c-family/

* c-omp.cc (omp_instantiate_mapper): Apply iterator to new clauses
generated from mapper.

gcc/c/

* c-parser.cc (c_parser_omp_clause_map): Apply iterator to push and
pop mapper clauses.

gcc/cp/

* parser.cc (cp_parser_omp_clause_map): Apply iterator to push and
pop mapper clauses.
* semantics.cc (cxx_omp_map_array_section): Allow array types for
base type of array sections.

libgomp/

* testsuite/libgomp.c-c++-common/mapper-iterators-1.c: New test.
* testsuite/libgomp.c-c++-common/mapper-iterators-2.c: New test.
* testsuite/libgomp.c-c++-common/mapper-iterators-3.c: New test.

Co-authored-by: Andrew Stubbs <ams@baylibre.com>
gcc/c-family/ChangeLog.omp
gcc/c-family/c-omp.cc
gcc/c/ChangeLog.omp
gcc/c/c-parser.cc
gcc/cp/ChangeLog.omp
gcc/cp/parser.cc
gcc/cp/semantics.cc
libgomp/ChangeLog.omp
libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-3.c [new file with mode: 0644]

index 9fe71baa001c131d5c52d14579e611d724b6caeb..1f2303a241f00f3cc49a155906e4841a850ec497 100644 (file)
@@ -1,3 +1,8 @@
+2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
+
+       * c-omp.cc (omp_instantiate_mapper): Apply iterator to new clauses
+       generated from mapper.
+
 2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
 
        * c-omp.cc (c_finish_omp_depobj): Use OMP_ITERATOR_DECL_P.
index ada8d8f0324083b75c3eb04581ee3e85cfa83e17..5c11e74fa739c92b50bb1573986d8f776340859a 100644 (file)
@@ -4759,6 +4759,7 @@ omp_instantiate_mapper (location_t loc, tree *outlist, tree mapper, tree expr,
   tree clauses = OMP_DECLARE_MAPPER_CLAUSES (mapper);
   tree dummy_var = OMP_DECLARE_MAPPER_DECL (mapper);
   tree mapper_name = NULL_TREE;
+  tree iterator = *outlist ? OMP_CLAUSE_ITERATORS (*outlist) : NULL_TREE;
 
   remap_mapper_decl_info map_info;
   map_info.dummy_var = dummy_var;
@@ -4887,6 +4888,7 @@ omp_instantiate_mapper (location_t loc, tree *outlist, tree mapper, tree expr,
        }
       else
        {
+         OMP_CLAUSE_ITERATORS (unshared) = iterator;
          *outlist = unshared;
          outlist = &OMP_CLAUSE_CHAIN (unshared);
        }
index 452c95f2a94c91ccd950317ca81d31162ba66e7f..e046bc4e60bd27df33e7e6e1017aa0ba5181f9b3 100644 (file)
@@ -1,3 +1,8 @@
+2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
+
+       * c-parser.cc (c_parser_omp_clause_map): Apply iterator to push and
+       pop mapper clauses.
+
 2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
 
        * c-parser.cc (c_parser_omp_iterators): Use macros for accessing
index c78c17a3a5cc0f6e9c8863df16113c5222acdc6a..5eaeaf8914be7d0d9e9c8881dad82e9f6fd87685 100644 (file)
@@ -19694,6 +19694,8 @@ c_parser_omp_clause_map (c_parser *parser, tree list, enum gomp_map_kind kind)
       tree name = build_omp_clause (input_location, OMP_CLAUSE_MAP);
       OMP_CLAUSE_SET_MAP_KIND (name, GOMP_MAP_PUSH_MAPPER_NAME);
       OMP_CLAUSE_DECL (name) = mapper_name;
+      if (iterators)
+       OMP_CLAUSE_ITERATORS (name) = iterators;
       OMP_CLAUSE_CHAIN (name) = nl;
       nl = name;
 
@@ -19702,6 +19704,8 @@ c_parser_omp_clause_map (c_parser *parser, tree list, enum gomp_map_kind kind)
       name = build_omp_clause (input_location, OMP_CLAUSE_MAP);
       OMP_CLAUSE_SET_MAP_KIND (name, GOMP_MAP_POP_MAPPER_NAME);
       OMP_CLAUSE_DECL (name) = null_pointer_node;
+      if (iterators)
+       OMP_CLAUSE_ITERATORS (name) = iterators;
       OMP_CLAUSE_CHAIN (name) = OMP_CLAUSE_CHAIN (last_new);
       OMP_CLAUSE_CHAIN (last_new) = name;
     }
index 9dde3721faad597a2655d16cf1c6fe63e43c66ff..80b4344a1b5b5e6b6db464b32dbd7cc9b5e85ed5 100644 (file)
@@ -1,3 +1,10 @@
+2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
+
+       * parser.cc (cp_parser_omp_clause_map): Apply iterator to push and
+       pop mapper clauses.
+       * semantics.cc (cxx_omp_map_array_section): Allow array types for
+       base type of array sections.
+
 2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
 
        * parser.cc (cp_parser_omp_iterators): Use macros for accessing
index a085c6b93cb502ae3878233ecd43843e88526a72..40cb3d9bab50eca01c68214cc151356f1ea15d95 100644 (file)
@@ -42916,6 +42916,8 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, enum gomp_map_kind kind)
       tree name = build_omp_clause (input_location, OMP_CLAUSE_MAP);
       OMP_CLAUSE_SET_MAP_KIND (name, GOMP_MAP_PUSH_MAPPER_NAME);
       OMP_CLAUSE_DECL (name) = mapper_name;
+      if (iterators)
+       OMP_CLAUSE_ITERATORS (name) = iterators;
       OMP_CLAUSE_CHAIN (name) = nlist;
       nlist = name;
 
@@ -42924,6 +42926,8 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, enum gomp_map_kind kind)
       name = build_omp_clause (input_location, OMP_CLAUSE_MAP);
       OMP_CLAUSE_SET_MAP_KIND (name, GOMP_MAP_POP_MAPPER_NAME);
       OMP_CLAUSE_DECL (name) = null_pointer_node;
+      if (iterators)
+       OMP_CLAUSE_ITERATORS (name) = iterators;
       OMP_CLAUSE_CHAIN (name) = OMP_CLAUSE_CHAIN (last_new);
       OMP_CLAUSE_CHAIN (last_new) = name;
     }
index 986a9cbe418853c780aedf23440236cb940e12da..c3eeeb4ef427c37c9c1e1980315e03eecccad1b5 100644 (file)
@@ -6611,7 +6611,8 @@ cxx_omp_map_array_section (location_t loc, tree t)
       if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
        t = convert_from_reference (t);
 
-      if (TYPE_PTR_P (TREE_TYPE (t)))
+      if (TYPE_PTR_P (TREE_TYPE (t))
+         || TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
        t = build_array_ref (loc, t, low);
       else
        t = error_mark_node;
index fca296cdb2092839f4f6246cd0d9b554df51c363..3612f1a419be2a2276e8f1021d66462b957affb3 100644 (file)
@@ -1,3 +1,9 @@
+2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
+
+       * testsuite/libgomp.c-c++-common/mapper-iterators-1.c: New test.
+       * testsuite/libgomp.c-c++-common/mapper-iterators-2.c: New test.
+       * testsuite/libgomp.c-c++-common/mapper-iterators-3.c: New test.
+
 2025-04-17  Kwok Cheung Yeung  <kcyeung@baylibre.com>
 
        * testsuite/libgomp.c-c++-common/target-map-iterators-4.c: New.
diff --git a/libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-1.c b/libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-1.c
new file mode 100644 (file)
index 0000000..1938237
--- /dev/null
@@ -0,0 +1,83 @@
+/* { dg-do run } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define DIM1 4
+#define DIM2 16
+
+struct S {
+  int *arr1;
+  float *arr2;
+  size_t len;
+};
+
+size_t
+mkarray (struct S arr[])
+{
+  size_t sum = 0;
+
+  for (int i = 0; i < DIM1; i++)
+    {
+      memset (&arr[i], 0, sizeof (struct S));
+      arr[i].len = DIM2;
+      arr[i].arr1 = (int *) calloc (arr[i].len, sizeof (int));
+      for (int j = 0; j < DIM2; j++)
+       {
+         size_t value = (i + 1) * (j + 1);
+         sum += value;
+         arr[i].arr1[j] = value;
+       }
+    }
+
+  return sum;
+}
+
+int main ()
+{
+  struct S arr[DIM1];
+  size_t sum = 0xdeadbeef;
+  size_t expected = mkarray (arr);
+
+  #pragma omp declare mapper (struct S x) \
+       map(to: x.arr1[0:DIM2]) \
+       map(to: x.arr2[0:DIM2]) \
+       map(to: x.len)
+
+  #pragma omp target map(iterator(int i=0:DIM1), to: arr[i]) map(from: sum)
+    {
+      sum = 0;
+#ifdef DEBUG
+      __builtin_printf ("&sum: %p\n", &sum);
+#endif
+      for (int i = 0; i < DIM1; i++)
+       {
+#ifdef DEBUG
+         __builtin_printf ("&arr[%d] = %p\n", i, &arr[i]);
+         __builtin_printf ("arr[%d].len = %d\n", i, arr[i].len);
+         __builtin_printf ("arr[%d].arr1 = %p\n", i, arr[i].arr1);
+         __builtin_printf ("arr[%d].arr2 = %p\n", i, arr[i].arr2);
+#endif
+         for (int j = 0; j < DIM2; j++)
+           {
+#ifdef DEBUG
+             __builtin_printf ("(i=%d,j=%d): %p\n", i, j, &arr[i].arr1[j]);
+             __builtin_printf ("(i=%d,j=%d): %d\n", i, j, arr[i].arr1[j]);
+#endif
+             sum += arr[i].arr1[j];
+#ifdef DEBUG
+             __builtin_printf ("sum: %ld\n", sum);
+#endif
+           }
+       }
+    }
+
+#ifdef DEBUG
+  __builtin_printf ("&sum: %p\n", &sum);
+  __builtin_printf ("sum:%zd (expected: %zd)\n", sum, expected);
+#endif
+
+  return sum != expected;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-2.c b/libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-2.c
new file mode 100644 (file)
index 0000000..76f00fb
--- /dev/null
@@ -0,0 +1,81 @@
+/* { dg-do run } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define DIM1 4
+#define DIM2 16
+
+#ifdef DEBUG
+#undef DEBUG
+#define DEBUG(...) __builtin_printf (__VA_ARGS__)
+#else
+#define DEBUG(...)
+#endif
+
+struct S {
+  int *arr1;
+  float *arr2;
+  size_t len;
+};
+
+size_t
+mkarray (struct S arr[])
+{
+  size_t sum = 0;
+
+  for (int i = 0; i < DIM1; i++)
+    {
+      memset (&arr[i], 0, sizeof (struct S));
+      arr[i].len = DIM2;
+      arr[i].arr1 = (int *) calloc (arr[i].len, sizeof (int));
+      for (int j = 0; j < DIM2; j++)
+       {
+         size_t value = (i + 1) * (j + 1);
+         sum += value;
+         arr[i].arr1[j] = value;
+       }
+    }
+
+  return sum;
+}
+
+int main ()
+{
+  struct S arr[DIM1];
+  size_t sum = 0xdeadbeef;
+  size_t expected = mkarray (arr);
+
+  #pragma omp declare mapper (struct S x) \
+       map(to: x.arr1[0:DIM2]) \
+       map(to: x.arr2[0:DIM2]) \
+       map(to: x.len)
+
+  /* This should be equivalent to map(iterator(int i=0:DIM1), to: arr[i])  */
+  #pragma omp target map(iterator(int i=0:DIM1:2, j=0:2), to: arr[i+j]) map(from: sum)
+    {
+      sum = 0;
+      DEBUG ("&sum: %p\n", &sum);
+      for (int i = 0; i < DIM1; i++)
+       {
+         DEBUG ("&arr[%d] = %p\n", i, &arr[i]);
+         DEBUG ("arr[%d].len = %d\n", i, arr[i].len);
+         DEBUG ("arr[%d].arr1 = %p\n", i, arr[i].arr1);
+         DEBUG ("arr[%d].arr2 = %p\n", i, arr[i].arr2);
+         for (int j = 0; j < DIM2; j++)
+           {
+             DEBUG ("(i=%d,j=%d): %p\n", i, j, &arr[i].arr1[j]);
+             DEBUG ("(i=%d,j=%d): %d\n", i, j, arr[i].arr1[j]);
+             sum += arr[i].arr1[j];
+             DEBUG ("sum: %ld\n", sum);
+           }
+       }
+    }
+
+  DEBUG ("&sum: %p\n", &sum);
+  DEBUG ("sum:%zd (expected: %zd)\n", sum, expected);
+
+  return sum != expected;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-3.c b/libgomp/testsuite/libgomp.c-c++-common/mapper-iterators-3.c
new file mode 100644 (file)
index 0000000..9d67c38
--- /dev/null
@@ -0,0 +1,98 @@
+/* { dg-do run } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define N 64
+#define DIM 4
+
+#ifdef DEBUG
+#undef DEBUG
+#define DEBUG(...) __builtin_printf (__VA_ARGS__)
+#else
+#define DEBUG(...)
+#endif
+
+typedef struct {
+  int *arr;
+  int size;
+} B;
+
+#pragma omp declare mapper (mapB : B myb) map(to: myb.size, myb.arr) \
+                                         map(tofrom: myb.arr[0:myb.size+1])
+
+struct A {
+  int *arr1;
+  B *arr2;
+  int arr3[N];
+};
+
+int
+main (int argc, char *argv[])
+{
+  struct A var[DIM];
+
+  for (int i=0; i < DIM; i++)
+    {
+      memset (&var[i], 0, sizeof var[i]);
+      var[i].arr1 = (int *) calloc (N, sizeof (int));
+      var[i].arr2 = (B *) malloc (sizeof (B));
+      var[i].arr2->arr = (int *) calloc (N+1, sizeof (float));
+      var[i].arr2->size = N+1;
+      DEBUG ("host &var[%d]:%p\n", i, &var[i]);
+      DEBUG ("host var[%d].arr1:%p\n", i, var[i].arr1);
+      DEBUG ("host var[%d].arr2:%p\n", i, var[i].arr2);
+      DEBUG ("host var[%d].arr2->arr:%p\n", i, var[i].arr2->arr);
+      DEBUG ("host var[%d].arr2->size:%d\n", i, var[i].arr2->size);
+    }
+
+  {
+    #pragma omp declare mapper (struct A x) map(to: x.arr1, x.arr2) \
+                         map(tofrom: x.arr1[0:N]) \
+                         map(mapper(mapB), tofrom: x.arr2[0:1])
+    #pragma omp target map(iterator(int i=0:DIM), tofrom: var[i])
+    {
+      for (int i = 0; i < DIM; i++)
+       {
+         DEBUG ("&var[%d]:%p\n", i, &var[i]);
+         DEBUG ("var[%d].arr1:%p\n", i, var[i].arr1);
+         DEBUG ("var[%d].arr2:%p\n", i, var[i].arr2);
+         if (var[i].arr2)
+           {
+             DEBUG ("var[%d].arr2->arr:%p\n", i, var[i].arr2->arr);
+             DEBUG ("var[%d].arr2->size:%d\n", i, var[i].arr2->size);
+           }
+         for (int j = 0; j < N; j++)
+           {
+             DEBUG ("&var[%d].arr1[%d]:%p\n", i, j, &var[i].arr1[j]);
+             var[i].arr1[j]++;
+             if (var[i].arr2)
+               {
+                 DEBUG ("&var[%d].arr2->arr[%d]:%p\n", i, j, &var[i].arr2->arr[j]);
+                 var[i].arr2->arr[j]++;
+               }
+             else
+               DEBUG ("SKIP arr2\n");
+           }
+       }
+    }
+  }
+
+  for (int i = 0; i < DIM; i++)
+    for (int j = 0; j < N; j++)
+      {
+       assert (var[i].arr1[j] == 1);
+       assert (var[i].arr2->arr[j] == 1);
+       assert (var[i].arr3[j] == 0);
+      }
+
+  for (int i = 0; i < DIM; i++)
+    {
+      free (var[i].arr1);
+      free (var[i].arr2->arr);
+      free (var[i].arr2);
+    }
+
+  return 0;
+}