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