1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/* { dg-do run } */
/* { dg-options "-O2" } */
int u[64], v, w[64];
__attribute__((noinline, noclone)) int
test (int a, int b, int c, int d, void (*fn) (int, int, int, int),
int *num_tasks, int *min_iters, int *max_iters, int *sep)
{
int i, j, t = 0;
__builtin_memset (u, 0, sizeof u);
v = 0;
fn (a, b, c, d);
*min_iters = 0;
*max_iters = 0;
*num_tasks = v;
*sep = v;
if (v)
{
*min_iters = u[0];
*max_iters = u[0];
t = u[0];
for (i = 1; i < v; i++)
{
if (*min_iters > u[i])
*min_iters = u[i];
if (*max_iters < u[i])
*max_iters = u[i];
t += u[i];
}
if (*min_iters != *max_iters)
{
for (i = 0; i < v - 1; i++)
{
int min_idx = i;
for (j = i + 1; j < v; j++)
if (w[min_idx] > w[j])
min_idx = j;
if (min_idx != i)
{
int tem = u[i];
u[i] = u[min_idx];
u[min_idx] = tem;
tem = w[i];
w[i] = w[min_idx];
w[min_idx] = tem;
}
}
if (u[0] != *max_iters)
__builtin_abort ();
for (i = 1; i < v; i++)
if (u[i] != u[i - 1])
{
if (*sep != v || u[i] != *min_iters)
__builtin_abort ();
*sep = i;
}
}
}
return t;
}
void
grainsize (int a, int b, int c, int d)
{
int i, j = 0, k = 0;
#pragma omp taskloop firstprivate (j, k) grainsize(strict:d)
for (i = a; i < b; i += c)
{
if (j == 0)
{
#pragma omp atomic capture
k = v++;
if (k >= 64)
__builtin_abort ();
w[k] = i;
}
u[k] = ++j;
}
}
void
num_tasks (int a, int b, int c, int d)
{
int i, j = 0, k = 0;
#pragma omp taskloop firstprivate (j, k) num_tasks(strict:d)
for (i = a; i < b; i += c)
{
if (j == 0)
{
#pragma omp atomic capture
k = v++;
if (k >= 64)
__builtin_abort ();
w[k] = i;
}
u[k] = ++j;
}
}
int
main ()
{
#pragma omp parallel
#pragma omp single
{
int min_iters, max_iters, ntasks, sep;
/* If grainsize is present and has strict modifier, # of task loop iters is == grainsize,
except that it can be smaller on the last task. */
if (test (0, 79, 1, 17, grainsize, &ntasks, &min_iters, &max_iters, &sep) != 79
|| ntasks != 5 || min_iters != 11 || max_iters != 17 || sep != 4)
__builtin_abort ();
if (test (-49, 2541, 7, 28, grainsize, &ntasks, &min_iters, &max_iters, &sep) != 370
|| ntasks != 14 || min_iters != 6 || max_iters != 28 || sep != 13)
__builtin_abort ();
if (test (7, 21, 2, 15, grainsize, &ntasks, &min_iters, &max_iters, &sep) != 7
|| ntasks != 1 || min_iters != 7 || max_iters != 7 || sep != 1)
__builtin_abort ();
/* If num_tasks is present, # of tasks is min (# of loop iters, num_tasks)
and each task has at least one iteration. If strict modifier is present,
first set of tasks has ceil (# of loop iters / num_tasks) iterations,
followed by possibly empty set of tasks with floor (# of loop iters / num_tasks)
iterations. */
if (test (-51, 2500, 48, 9, num_tasks, &ntasks, &min_iters, &max_iters, &sep) != 54
|| ntasks != 9 || min_iters != 6 || max_iters != 6 || sep != 9)
__builtin_abort ();
if (test (0, 57, 1, 9, num_tasks, &ntasks, &min_iters, &max_iters, &sep) != 57
|| ntasks != 9 || min_iters != 6 || max_iters != 7 || sep != 3)
__builtin_abort ();
if (test (0, 25, 2, 17, num_tasks, &ntasks, &min_iters, &max_iters, &sep) != 13
|| ntasks != 13 || min_iters != 1 || max_iters != 1 || sep != 13)
__builtin_abort ();
}
return 0;
}
|