xref: /llvm-project/openmp/runtime/test/tasking/omp_taskloop_grainsize.c (revision ed5fe64581f4f076c00d5e57caff1ff746d57c79)
193e17cfeSJonathan Peyton // RUN: %libomp-compile-and-run
293e17cfeSJonathan Peyton // RUN: %libomp-compile && env KMP_TASKLOOP_MIN_TASKS=1 %libomp-run
35b57eb4bSJonas Hahnfeld 
45b57eb4bSJonas Hahnfeld // These compilers don't support the taskloop construct
55b57eb4bSJonas Hahnfeld // UNSUPPORTED: gcc-4, gcc-5, icc-16
65b57eb4bSJonas Hahnfeld // GCC 6 has support for taskloops, but at least 6.3.0 is crashing on this test
75b57eb4bSJonas Hahnfeld // UNSUPPORTED: gcc-6
85b57eb4bSJonas Hahnfeld 
993e17cfeSJonathan Peyton /*
1093e17cfeSJonathan Peyton  * Test for taskloop
11*ed5fe645SKelvin Li  * Method: calculate how many times the iteration space is dispatched
1293e17cfeSJonathan Peyton  *     and judge if each dispatch has the requested grainsize
1393e17cfeSJonathan Peyton  * It is possible for two adjacent chunks are executed by the same thread
1493e17cfeSJonathan Peyton  */
1593e17cfeSJonathan Peyton #include <stdio.h>
1693e17cfeSJonathan Peyton #include <omp.h>
1793e17cfeSJonathan Peyton #include <stdlib.h>
1893e17cfeSJonathan Peyton #include "omp_testsuite.h"
1993e17cfeSJonathan Peyton 
2093e17cfeSJonathan Peyton #define CFDMAX_SIZE 1120
2193e17cfeSJonathan Peyton 
test_omp_taskloop_grainsize()2293e17cfeSJonathan Peyton int test_omp_taskloop_grainsize()
2393e17cfeSJonathan Peyton {
245872f1e9SJonas Hahnfeld   int result = 0;
255872f1e9SJonas Hahnfeld   int i, grainsize, count, tmp_count, num_off;
2693e17cfeSJonathan Peyton   int *tmp, *tids, *tidsArray;
2793e17cfeSJonathan Peyton 
2893e17cfeSJonathan Peyton   tidsArray = (int *)malloc(sizeof(int) * CFDMAX_SIZE);
2993e17cfeSJonathan Peyton   tids = tidsArray;
3093e17cfeSJonathan Peyton 
3193e17cfeSJonathan Peyton   for (grainsize = 1; grainsize < 48; ++grainsize) {
3293e17cfeSJonathan Peyton     fprintf(stderr, "Grainsize %d\n", grainsize);
3393e17cfeSJonathan Peyton     count = tmp_count = num_off = 0;
3493e17cfeSJonathan Peyton 
3593e17cfeSJonathan Peyton     for (i = 0; i < CFDMAX_SIZE; ++i) {
3693e17cfeSJonathan Peyton       tids[i] = -1;
3793e17cfeSJonathan Peyton     }
3893e17cfeSJonathan Peyton 
3993e17cfeSJonathan Peyton     #pragma omp parallel shared(tids)
4093e17cfeSJonathan Peyton     {
4193e17cfeSJonathan Peyton       #pragma omp master
4293e17cfeSJonathan Peyton       #pragma omp taskloop grainsize(grainsize)
4393e17cfeSJonathan Peyton       for (i = 0; i < CFDMAX_SIZE; i++) {
4493e17cfeSJonathan Peyton         tids[i] = omp_get_thread_num();
4593e17cfeSJonathan Peyton       }
4693e17cfeSJonathan Peyton     }
4793e17cfeSJonathan Peyton 
4893e17cfeSJonathan Peyton     for (i = 0; i < CFDMAX_SIZE; ++i) {
4993e17cfeSJonathan Peyton       if (tids[i] == -1) {
5093e17cfeSJonathan Peyton         fprintf(stderr, "  Iteration %d not touched!\n", i);
5193e17cfeSJonathan Peyton         result++;
5293e17cfeSJonathan Peyton       }
5393e17cfeSJonathan Peyton     }
5493e17cfeSJonathan Peyton 
5593e17cfeSJonathan Peyton     for (i = 0; i < CFDMAX_SIZE - 1; ++i) {
5693e17cfeSJonathan Peyton       if (tids[i] != tids[i + 1]) {
5793e17cfeSJonathan Peyton         count++;
5893e17cfeSJonathan Peyton       }
5993e17cfeSJonathan Peyton     }
6093e17cfeSJonathan Peyton 
6193e17cfeSJonathan Peyton     tmp = (int *)malloc(sizeof(int) * (count + 1));
6293e17cfeSJonathan Peyton     tmp[0] = 1;
6393e17cfeSJonathan Peyton 
6493e17cfeSJonathan Peyton     for (i = 0; i < CFDMAX_SIZE - 1; ++i) {
6593e17cfeSJonathan Peyton       if (tmp_count > count) {
6693e17cfeSJonathan Peyton         printf("--------------------\nTestinternal Error: List too "
6793e17cfeSJonathan Peyton                "small!!!\n--------------------\n");
6893e17cfeSJonathan Peyton         break;
6993e17cfeSJonathan Peyton       }
7093e17cfeSJonathan Peyton       if (tids[i] != tids[i + 1]) {
7193e17cfeSJonathan Peyton         tmp_count++;
7293e17cfeSJonathan Peyton         tmp[tmp_count] = 1;
7393e17cfeSJonathan Peyton       } else {
7493e17cfeSJonathan Peyton         tmp[tmp_count]++;
7593e17cfeSJonathan Peyton       }
7693e17cfeSJonathan Peyton     }
7793e17cfeSJonathan Peyton 
7893e17cfeSJonathan Peyton     // is grainsize statement working?
7993e17cfeSJonathan Peyton     int num_tasks = CFDMAX_SIZE / grainsize;
8093e17cfeSJonathan Peyton     int multiple1 = CFDMAX_SIZE / num_tasks;
8193e17cfeSJonathan Peyton     int multiple2 = CFDMAX_SIZE / num_tasks + 1;
8293e17cfeSJonathan Peyton     for (i = 0; i < count; i++) {
8393e17cfeSJonathan Peyton       // it is possible for 2 adjacent chunks assigned to a same thread
8493e17cfeSJonathan Peyton       if (tmp[i] % multiple1 != 0 && tmp[i] % multiple2 != 0) {
8593e17cfeSJonathan Peyton         num_off++;
8693e17cfeSJonathan Peyton       }
8793e17cfeSJonathan Peyton     }
8893e17cfeSJonathan Peyton 
8993e17cfeSJonathan Peyton     if (num_off > 1) {
9093e17cfeSJonathan Peyton       fprintf(stderr, "  The number of bad chunks is %d\n", num_off);
9193e17cfeSJonathan Peyton       result++;
9293e17cfeSJonathan Peyton     } else {
9393e17cfeSJonathan Peyton       fprintf(stderr, "  Everything ok\n");
9493e17cfeSJonathan Peyton     }
9593e17cfeSJonathan Peyton 
9693e17cfeSJonathan Peyton     free(tmp);
9793e17cfeSJonathan Peyton   }
9893e17cfeSJonathan Peyton   free(tidsArray);
9993e17cfeSJonathan Peyton   return (result==0);
10093e17cfeSJonathan Peyton }
10193e17cfeSJonathan Peyton 
main()10293e17cfeSJonathan Peyton int main()
10393e17cfeSJonathan Peyton {
10493e17cfeSJonathan Peyton   int i;
10593e17cfeSJonathan Peyton   int num_failed=0;
10693e17cfeSJonathan Peyton 
10793e17cfeSJonathan Peyton   for (i = 0; i < REPETITIONS; i++) {
10893e17cfeSJonathan Peyton     if (!test_omp_taskloop_grainsize()) {
10993e17cfeSJonathan Peyton       num_failed++;
11093e17cfeSJonathan Peyton     }
11193e17cfeSJonathan Peyton   }
11293e17cfeSJonathan Peyton   return num_failed;
11393e17cfeSJonathan Peyton }
114