Jim Cownie | 18d8473 | 2014-05-10 17:02:09 +0000 | [diff] [blame] | 1 | <ompts:test> |
| 2 | <ompts:testdescription>Test which checks the omp threadprivate directive by filling an array with random numbers in an parallelised region. Each thread generates one number of the array and saves this in a temporary threadprivate variable. In a second parallelised region the test controls, that the temporary variable contains still the former value by comparing it with the one in the array.</ompts:testdescription> |
| 3 | <ompts:ompversion>2.0</ompts:ompversion> |
| 4 | <ompts:directive>omp threadprivate</ompts:directive> |
| 5 | <ompts:dependences>omp critical,omp_set_dynamic,omp_get_num_threads</ompts:dependences> |
| 6 | <ompts:testcode> |
| 7 | /* |
| 8 | * Threadprivate is tested in 2 ways: |
| 9 | * 1. The global variable declared as threadprivate should have |
| 10 | * local copy for each thread. Otherwise race condition and |
| 11 | * wrong result. |
| 12 | * 2. If the value of local copy is retained for the two adjacent |
| 13 | * parallel regions |
| 14 | */ |
| 15 | #include "omp_testsuite.h" |
| 16 | #include <stdlib.h> |
| 17 | #include <stdio.h> |
| 18 | |
| 19 | static int sum0=0; |
| 20 | static int myvalue = 0; |
| 21 | |
| 22 | <ompts:check>#pragma omp threadprivate(sum0)</ompts:check> |
| 23 | <ompts:check>#pragma omp threadprivate(myvalue)</ompts:check> |
| 24 | |
| 25 | |
| 26 | int <ompts:testcode:functionname>omp_threadprivate</ompts:testcode:functionname>(FILE * logFile) |
| 27 | { |
| 28 | int sum = 0; |
| 29 | int known_sum; |
| 30 | int i; |
| 31 | int iter; |
| 32 | int *data; |
| 33 | int size; |
| 34 | int failed = 0; |
| 35 | int my_random; |
| 36 | omp_set_dynamic(0); |
| 37 | |
| 38 | #pragma omp parallel private(i) |
| 39 | { |
| 40 | sum0 = 0; |
| 41 | #pragma omp for |
| 42 | for (i = 1; i <= LOOPCOUNT; i++) |
| 43 | { |
| 44 | sum0 = sum0 + i; |
| 45 | } /*end of for*/ |
| 46 | #pragma omp critical |
| 47 | { |
| 48 | sum = sum + sum0; |
| 49 | } /*end of critical */ |
| 50 | } /* end of parallel */ |
| 51 | known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2; |
| 52 | if (known_sum != sum ) { |
| 53 | fprintf (logFile, " known_sum = %d, sum = %d\n", known_sum, sum); |
| 54 | } |
| 55 | |
| 56 | /* the next parallel region is just used to get the number of threads*/ |
| 57 | omp_set_dynamic(0); |
| 58 | #pragma omp parallel |
| 59 | { |
| 60 | #pragma omp master |
| 61 | { |
| 62 | size=omp_get_num_threads(); |
| 63 | data=(int*) malloc(size*sizeof(int)); |
| 64 | } |
| 65 | }/* end parallel*/ |
| 66 | |
| 67 | |
| 68 | srand(45); |
| 69 | for (iter = 0; iter < 100; iter++){ |
| 70 | my_random = rand(); /* random number generator is called inside serial region*/ |
| 71 | |
| 72 | /* the first parallel region is used to initialiye myvalue and the array with my_random+rank*/ |
| 73 | #pragma omp parallel |
| 74 | { |
| 75 | int rank; |
| 76 | rank = omp_get_thread_num (); |
| 77 | myvalue = data[rank] = my_random + rank; |
| 78 | } |
| 79 | |
| 80 | /* the second parallel region verifies that the value of "myvalue" is retained */ |
| 81 | #pragma omp parallel reduction(+:failed) |
| 82 | { |
| 83 | int rank; |
| 84 | rank = omp_get_thread_num (); |
| 85 | failed = failed + (myvalue != data[rank]); |
| 86 | if(myvalue != data[rank]){ |
| 87 | fprintf (logFile, " myvalue = %d, data[rank]= %d\n", myvalue, data[rank]); |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | free (data); |
| 92 | |
| 93 | return (known_sum == sum) && !failed; |
| 94 | |
| 95 | } /* end of check_threadprivate*/ |
| 96 | </ompts:testcode> |
| 97 | </ompts:test> |