1 struct S { int a, b, c[2]; };
2 #pragma omp declare reduction (+: struct S : (omp_out.a += omp_in.a, omp_out.b += omp_in.b)) \
3 initializer (omp_priv = { 0, 0, { 0, 0 } })
4
5 void
6 foo (struct S x, struct S *y, int n, int v)
7 {
8 struct S z[3] = { { 45, 47, {} }, { 46, 48, {} }, { 47, 49, {} } };
9 struct S u[n], w[n];
10 int i;
11 for (i = 0; i < n; i++)
12 {
13 w[i].a = u[i].a = n + i;
14 w[i].b = u[i].b = n - i;
15 w[i].c[0] = u[i].c[0] = 0;
16 w[i].c[1] = u[i].c[1] = 0;
17 }
18 #pragma omp taskgroup task_reduction (+: x, y[:2], z[1:2], u, w[1:v])
19 {
20 #pragma omp task in_reduction (+: x, y[:2], z[1:2], u, w[1:v])
21 {
22 x.a++;
23 x.b++;
24 y[0].a += 2;
25 y[0].b += 12;
26 y[1].a += 3;
27 y[1].b += 13;
28 z[1].a += 4;
29 z[1].b += 14;
30 u[0].a += 5;
31 u[0].b += 15;
32 w[1].a += 6;
33 w[1].b += 16;
34 }
35 #pragma omp target in_reduction (+: x, y[:2], z[1:2], u, w[1:v]) map(tofrom: x.a, x.b, x.c[:2])
36 {
37 x.a += 4;
38 x.b += 14;
39 y[0].a += 5;
40 y[0].b += 15;
41 y[1].a += 6;
42 y[1].b += 16;
43 z[2].a += 7;
44 z[2].b += 17;
45 u[1].a += 8;
46 u[1].b += 18;
47 w[2].a += 7;
48 w[2].b += 17;
49 }
50 #pragma omp target in_reduction (+: x, y[:v], z[1:v], u, w[1:2])
51 {
52 x.a += 9;
53 x.b += 19;
54 y[0].a += 10;
55 y[0].b += 20;
56 y[1].a += 11;
57 y[1].b += 21;
58 z[1].a += 12;
59 z[1].b += 22;
60 u[2].a += 13;
61 u[2].b += 23;
62 w[1].a += 14;
63 w[1].b += 24;
64 }
65 }
66 if (x.a != 56 || y[0].a != 60 || y[1].a != 64)
67 __builtin_abort ();
68 if (x.b != 86 || y[0].b != 100 || y[1].b != 104)
69 __builtin_abort ();
70 if (z[0].a != 45 || z[1].a != 62 || z[2].a != 54)
71 __builtin_abort ();
72 if (z[0].b != 47 || z[1].b != 84 || z[2].b != 66)
73 __builtin_abort ();
74 if (u[0].a != 8 || u[1].a != 12 || u[2].a != 18)
75 __builtin_abort ();
76 if (u[0].b != 18 || u[1].b != 20 || u[2].b != 24)
77 __builtin_abort ();
78 if (w[0].a != 3 || w[1].a != 24 || w[2].a != 12)
79 __builtin_abort ();
80 if (w[0].b != 3 || w[1].b != 42 || w[2].b != 18)
81 __builtin_abort ();
82 }
83
84 void
85 bar (struct S x, struct S *y, int n, int v)
86 {
87 struct S z[3] = { { 45, 47, {} }, { 46, 48, {} }, { 47, 49, {} } };
88 struct S u[n], w[n];
89 int i;
90 for (i = 0; i < n; i++)
91 {
92 w[i].a = u[i].a = n + i;
93 w[i].b = u[i].b = n - i;
94 w[i].c[0] = u[i].c[0] = 0;
95 w[i].c[1] = u[i].c[1] = 0;
96 }
97 #pragma omp parallel master
98 #pragma omp taskgroup task_reduction (+: x, y[:2], z[1:2], u, w[1:v])
99 {
100 #pragma omp task in_reduction (+: x, y[:2], z[1:2], u, w[1:v])
101 {
102 x.a++;
103 x.b++;
104 y[0].a += 2;
105 y[0].b += 12;
106 y[1].a += 3;
107 y[1].b += 13;
108 z[1].a += 4;
109 z[1].b += 14;
110 u[0].a += 5;
111 u[0].b += 15;
112 w[1].a += 6;
113 w[1].b += 16;
114 }
115 #pragma omp target in_reduction (+: x, y[:2], z[1:2], u, w[1:v]) map(tofrom: x.a, x.b, x.c[:2])
116 {
117 x.a += 4;
118 x.b += 14;
119 y[0].a += 5;
120 y[0].b += 15;
121 y[1].a += 6;
122 y[1].b += 16;
123 z[2].a += 7;
124 z[2].b += 17;
125 u[1].a += 8;
126 u[1].b += 18;
127 w[2].a += 7;
128 w[2].b += 17;
129 }
130 #pragma omp target in_reduction (+: x, y[:v], z[1:v], u, w[1:2])
131 {
132 x.a += 9;
133 x.b += 19;
134 y[0].a += 10;
135 y[0].b += 20;
136 y[1].a += 11;
137 y[1].b += 21;
138 z[1].a += 12;
139 z[1].b += 22;
140 u[2].a += 13;
141 u[2].b += 23;
142 w[1].a += 14;
143 w[1].b += 24;
144 }
145 }
146 if (x.a != 56 || y[0].a != 77 || y[1].a != 84)
147 __builtin_abort ();
148 if (x.b != 86 || y[0].b != 147 || y[1].b != 154)
149 __builtin_abort ();
150 if (z[0].a != 45 || z[1].a != 62 || z[2].a != 54)
151 __builtin_abort ();
152 if (z[0].b != 47 || z[1].b != 84 || z[2].b != 66)
153 __builtin_abort ();
154 if (u[0].a != 8 || u[1].a != 12 || u[2].a != 18)
155 __builtin_abort ();
156 if (u[0].b != 18 || u[1].b != 20 || u[2].b != 24)
157 __builtin_abort ();
158 if (w[0].a != 3 || w[1].a != 24 || w[2].a != 12)
159 __builtin_abort ();
160 if (w[0].b != 3 || w[1].b != 42 || w[2].b != 18)
161 __builtin_abort ();
162 }
163
164 int
165 main ()
166 {
167 struct S x = { 42, 52 };
168 struct S y[2] = { { 43, 53 }, { 44, 54 } };
169 #pragma omp parallel master
170 foo (x, y, 3, 2);
171 bar (x, y, 3, 2);
172 return 0;
173 }