1 extern
2 #ifdef __cplusplus
3 "C"
4 #endif
5 void abort (void);
6
7 struct S { unsigned long long int s, t; };
8
9 void
10 rbar (struct S *p, struct S *o)
11 {
12 p->s = 1;
13 if (o->t != 5)
14 abort ();
15 p->t = 9;
16 }
17
18 static inline void
19 rbaz (struct S *o, struct S *i)
20 {
21 if (o->t != 5 || i->t != 9)
22 abort ();
23 o->s *= i->s;
24 }
25
26 #pragma omp declare reduction (+: struct S : omp_out.s += omp_in.s) \
27 initializer (omp_priv = { 0, 3 })
28 #pragma omp declare reduction (*: struct S : rbaz (&omp_out, &omp_in)) \
29 initializer (rbar (&omp_priv, &omp_orig))
30
31 struct S g = { 0, 7 };
32 struct S h = { 1, 5 };
33
34 int
35 foo (int *a, int *b)
36 {
37 int x = 0;
38 #pragma omp taskloop reduction (+:x) in_reduction (+:b[0])
39 for (int i = 0; i < 64; i++)
40 {
41 x += a[i];
42 *b += a[i] * 2;
43 }
44 return x;
45 }
46
47 unsigned long long int
48 bar (int *a, unsigned long long int *b)
49 {
50 unsigned long long int x = 1;
51 #pragma omp taskloop reduction (*:x) in_reduction (*:b[0])
52 for (int i = 0; i < 64; i++)
53 {
54 #pragma omp task in_reduction (*:x)
55 x *= a[i];
56 #pragma omp task in_reduction (*:b[0])
57 *b *= (3 - a[i]);
58 }
59 return x;
60 }
61
62 void
63 baz (int i, int *a, int *c)
64 {
65 #pragma omp task in_reduction (*:h) in_reduction (+:g)
66 {
67 g.s += 7 * a[i];
68 h.s *= (3 - c[i]);
69 if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9))
70 abort ();
71 }
72 }
73
74 int
75 main ()
76 {
77 int i, j, a[64], b = 0, c[64];
78 unsigned long long int d = 1, e;
79 struct S m = { 0, 7 };
80 for (i = 0; i < 64; i++)
81 {
82 a[i] = 2 * i;
83 c[i] = 1 + ((i % 3) != 1);
84 }
85 #pragma omp parallel
86 #pragma omp master
87 {
88 struct S n = { 1, 5 };
89 #pragma omp taskgroup task_reduction (+:b)
90 j = foo (a, &b);
91 #pragma omp taskgroup task_reduction (*:d)
92 e = bar (c, &d);
93 #pragma omp taskloop reduction (+: g, m) reduction (*: h, n)
94 for (i = 0; i < 64; ++i)
95 {
96 g.s += 3 * a[i];
97 h.s *= (3 - c[i]);
98 m.s += 4 * a[i];
99 n.s *= c[i];
100 if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9)
101 || (m.t != 7 && m.t != 3) || (n.t != 5 && n.t != 9))
102 abort ();
103 baz (i, a, c);
104 }
105 if (n.s != (1ULL << 43) || n.t != 5)
106 abort ();
107 }
108 if (j != 63 * 64 || b != 63 * 64 * 2)
109 abort ();
110 if (e != (1ULL << 43) || d != (1ULL << 21))
111 abort ();
112 if (g.s != 63 * 64 * 10 || g.t != 7)
113 abort ();
114 if (h.s != (1ULL << 42) || h.t != 5)
115 abort ();
116 if (m.s != 63 * 64 * 4 || m.t != 7)
117 abort ();
118 return 0;
119 }