1 // RUN: %libomp-compile-and-run
2 // RUN: %libomp-compile && env KMP_TASKLOOP_MIN_TASKS=1 %libomp-run
3 // UNSUPPORTED: gcc
4 // We do not yet have the GOMP interface for taskloop
5 /*
6  * Test for taskloop
7  * Method: caculate how many times the iteration space is dispatched
8  *     and judge if each dispatch has the requested grainsize
9  * It is possible for two adjacent chunks are executed by the same thread
10  */
11 #include <stdio.h>
12 #include <omp.h>
13 #include <stdlib.h>
14 #include "omp_testsuite.h"
15 
16 #define CFDMAX_SIZE 1120
17 
18 int test_omp_taskloop_grainsize()
19 {
20   int i, grainsize, count, tmp_count, result, num_off;
21   int *tmp, *tids, *tidsArray;
22 
23   tidsArray = (int *)malloc(sizeof(int) * CFDMAX_SIZE);
24   tids = tidsArray;
25 
26   for (grainsize = 1; grainsize < 48; ++grainsize) {
27     fprintf(stderr, "Grainsize %d\n", grainsize);
28     count = tmp_count = num_off = 0;
29 
30     for (i = 0; i < CFDMAX_SIZE; ++i) {
31       tids[i] = -1;
32     }
33 
34     #pragma omp parallel shared(tids)
35     {
36       #pragma omp master
37       #pragma omp taskloop grainsize(grainsize)
38       for (i = 0; i < CFDMAX_SIZE; i++) {
39         tids[i] = omp_get_thread_num();
40       }
41     }
42 
43     for (i = 0; i < CFDMAX_SIZE; ++i) {
44       if (tids[i] == -1) {
45         fprintf(stderr, "  Iteration %d not touched!\n", i);
46         result++;
47       }
48     }
49 
50     for (i = 0; i < CFDMAX_SIZE - 1; ++i) {
51       if (tids[i] != tids[i + 1]) {
52         count++;
53       }
54     }
55 
56     tmp = (int *)malloc(sizeof(int) * (count + 1));
57     tmp[0] = 1;
58 
59     for (i = 0; i < CFDMAX_SIZE - 1; ++i) {
60       if (tmp_count > count) {
61         printf("--------------------\nTestinternal Error: List too "
62                "small!!!\n--------------------\n");
63         break;
64       }
65       if (tids[i] != tids[i + 1]) {
66         tmp_count++;
67         tmp[tmp_count] = 1;
68       } else {
69         tmp[tmp_count]++;
70       }
71     }
72 
73     // is grainsize statement working?
74     int num_tasks = CFDMAX_SIZE / grainsize;
75     int multiple1 = CFDMAX_SIZE / num_tasks;
76     int multiple2 = CFDMAX_SIZE / num_tasks + 1;
77     for (i = 0; i < count; i++) {
78       // it is possible for 2 adjacent chunks assigned to a same thread
79       if (tmp[i] % multiple1 != 0 && tmp[i] % multiple2 != 0) {
80         num_off++;
81       }
82     }
83 
84     if (num_off > 1) {
85       fprintf(stderr, "  The number of bad chunks is %d\n", num_off);
86       result++;
87     } else {
88       fprintf(stderr, "  Everything ok\n");
89     }
90 
91     free(tmp);
92   }
93   free(tidsArray);
94   return (result==0);
95 }
96 
97 int main()
98 {
99   int i;
100   int num_failed=0;
101 
102   for (i = 0; i < REPETITIONS; i++) {
103     if (!test_omp_taskloop_grainsize()) {
104       num_failed++;
105     }
106   }
107   return num_failed;
108 }
109