1 #include <omp.h>
2 #include <stdlib.h>
3 
4 __attribute__((noinline))
5 void
foo(int x,int y,int z,int * a,int * b)6 foo (int x, int y, int z, int *a, int *b)
7 {
8   if (x == 0)
9     {
10       int i, j;
11       for (i = 0; i < 64; i++)
12 	#pragma omp parallel for shared (a, b)
13 	for (j = 0; j < 32; j++)
14 	  foo (3, i, j, a, b);
15     }
16   else if (x == 1)
17     {
18       int i, j;
19       #pragma omp distribute dist_schedule (static, 1)
20       for (i = 0; i < 64; i++)
21 	#pragma omp parallel for shared (a, b)
22 	for (j = 0; j < 32; j++)
23 	  foo (3, i, j, a, b);
24     }
25   else if (x == 2)
26     {
27       int j;
28       #pragma omp parallel for shared (a, b)
29       for (j = 0; j < 32; j++)
30 	foo (3, y, j, a, b);
31     }
32   else
33     {
34       #pragma omp atomic
35       b[y] += z;
36       #pragma omp atomic
37       *a += 1;
38     }
39 }
40 
41 __attribute__((noinline))
42 int
bar(int x,int y,int z)43 bar (int x, int y, int z)
44 {
45   int a, b[64], i;
46   a = 8;
47   for (i = 0; i < 64; i++)
48     b[i] = i;
49   foo (x, y, z, &a, b);
50   if (x == 0)
51     {
52       if (a != 8 + 64 * 32)
53 	return 1;
54       for (i = 0; i < 64; i++)
55 	if (b[i] != i + 31 * 32 / 2)
56 	  return 1;
57     }
58   else if (x == 1)
59     {
60       int c = omp_get_num_teams ();
61       int d = omp_get_team_num ();
62       int e = d;
63       int f = 0;
64       for (i = 0; i < 64; i++)
65 	if (i == e)
66 	  {
67 	    if (b[i] != i + 31 * 32 / 2)
68 	      return 1;
69 	    f++;
70 	    e = e + c;
71 	  }
72 	else if (b[i] != i)
73 	  return 1;
74       if (a < 8 || a > 8 + f * 32)
75 	return 1;
76     }
77   else if (x == 2)
78     {
79       if (a != 8 + 32)
80 	return 1;
81       for (i = 0; i < 64; i++)
82 	if (b[i] != i + (i == y ? 31 * 32 / 2 : 0))
83 	  return 1;
84     }
85   else if (x == 3)
86     {
87       if (a != 8 + 1)
88 	return 1;
89       for (i = 0; i < 64; i++)
90 	if (b[i] != i + (i == y ? z : 0))
91 	  return 1;
92     }
93   return 0;
94 }
95 
96 int
main()97 main ()
98 {
99   int i, j, err = 0;
100   #pragma omp teams reduction(+:err)
101   err += bar (0, 0, 0);
102   if (err)
103     abort ();
104   #pragma omp teams reduction(+:err)
105   err += bar (1, 0, 0);
106   if (err)
107     abort ();
108   #pragma omp teams reduction(+:err)
109   #pragma omp distribute
110   for (i = 0; i < 64; i++)
111     err += bar (2, i, 0);
112   if (err)
113     abort ();
114   #pragma omp teams reduction(+:err)
115   #pragma omp distribute
116   for (i = 0; i < 64; i++)
117   #pragma omp parallel for reduction(+:err)
118     for (j = 0; j < 32; j++)
119       err += bar (3, i, j);
120   if (err)
121     abort ();
122   return 0;
123 }
124