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 result = 0;
21   int i, grainsize, count, tmp_count, num_off;
22   int *tmp, *tids, *tidsArray;
23 
24   tidsArray = (int *)malloc(sizeof(int) * CFDMAX_SIZE);
25   tids = tidsArray;
26 
27   for (grainsize = 1; grainsize < 48; ++grainsize) {
28     fprintf(stderr, "Grainsize %d\n", grainsize);
29     count = tmp_count = num_off = 0;
30 
31     for (i = 0; i < CFDMAX_SIZE; ++i) {
32       tids[i] = -1;
33     }
34 
35     #pragma omp parallel shared(tids)
36     {
37       #pragma omp master
38       #pragma omp taskloop grainsize(grainsize)
39       for (i = 0; i < CFDMAX_SIZE; i++) {
40         tids[i] = omp_get_thread_num();
41       }
42     }
43 
44     for (i = 0; i < CFDMAX_SIZE; ++i) {
45       if (tids[i] == -1) {
46         fprintf(stderr, "  Iteration %d not touched!\n", i);
47         result++;
48       }
49     }
50 
51     for (i = 0; i < CFDMAX_SIZE - 1; ++i) {
52       if (tids[i] != tids[i + 1]) {
53         count++;
54       }
55     }
56 
57     tmp = (int *)malloc(sizeof(int) * (count + 1));
58     tmp[0] = 1;
59 
60     for (i = 0; i < CFDMAX_SIZE - 1; ++i) {
61       if (tmp_count > count) {
62         printf("--------------------\nTestinternal Error: List too "
63                "small!!!\n--------------------\n");
64         break;
65       }
66       if (tids[i] != tids[i + 1]) {
67         tmp_count++;
68         tmp[tmp_count] = 1;
69       } else {
70         tmp[tmp_count]++;
71       }
72     }
73 
74     // is grainsize statement working?
75     int num_tasks = CFDMAX_SIZE / grainsize;
76     int multiple1 = CFDMAX_SIZE / num_tasks;
77     int multiple2 = CFDMAX_SIZE / num_tasks + 1;
78     for (i = 0; i < count; i++) {
79       // it is possible for 2 adjacent chunks assigned to a same thread
80       if (tmp[i] % multiple1 != 0 && tmp[i] % multiple2 != 0) {
81         num_off++;
82       }
83     }
84 
85     if (num_off > 1) {
86       fprintf(stderr, "  The number of bad chunks is %d\n", num_off);
87       result++;
88     } else {
89       fprintf(stderr, "  Everything ok\n");
90     }
91 
92     free(tmp);
93   }
94   free(tidsArray);
95   return (result==0);
96 }
97 
98 int main()
99 {
100   int i;
101   int num_failed=0;
102 
103   for (i = 0; i < REPETITIONS; i++) {
104     if (!test_omp_taskloop_grainsize()) {
105       num_failed++;
106     }
107   }
108   return num_failed;
109 }
110