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