A THREADPRIVATE array is incorrectly used to pass data between parallel regions.
The THREADPRIVATE directive specifies that variables are replicated, with each thread having its own copy. Because OpenMP* assigns work to threads in a somewhat unpredictable fashion, the value of a particular thread's copy becomes indeterminate after a scheduling point. These error diagnostic flags cases where a THREADPRIVATE variable was read when its value was in an indeterminate state.
There are two main ways a THREADPRIVATE variable can become indeterminate. One case is when leaving a parallel region in which the variable was modified. The problem here is that it is generally impossible to predict which threads will have executed which assignments. Another case is when entering a parallel region. The problem here is that it is generally impossible to predict which threads will be enlisted to join the team that executes the region. If a parallel region has a COPYIN clause, then the copy of that variable for each member of the team is initialized on entry from the copy of that variable belonging to the master thread.
Specifically, this message flags the case where a value was assigned to a THREADPRIVATE array variable in one parallel region and then read in another parallel region and the two references were indexed differently. For example, one loop might refer to "a[i]", and another loop to "a[i+1]". Under these conditions, you cannot be sure that the same thread will access the same array element in both loops.
Usually this error indicates that a THREADPRIVATE variable is not appropriate for the specific usage pattern. It may be necessary to restructure the parallel regions to unify operations that are done in separate regions, or it may be necessary to flatten out the data between the two parallel regions without using THREADPRIVATE variables.
ID |
Observation |
Description |
---|---|---|
1 |
Bad memory access |
The place where the value was referenced |
2 |
OpenMP declaration |
The place where the value was earlier defined |
3 |
OpenMP declaration |
The region where the value was earlier defined |
#include <stdio.h> #include <omp.h> int a[1000]; #pragma omp threadprivate (a) int main(int argc, char **argv) { int i; int sum = 0; // Here we have the two parallel loops that will map loop interations // to threads in exactly the same way, but the threadprivate // array "a" cannot be used to pass values from the first loop to // the second because the arrays are not indexed in the same way. // // For example, suppose even iterations are assigned to // thread T1 and odd iterations are assigned to thread T2. // Then the first loop will initialize the even elements // of T1's copy of "a" and the odd elements of T2's copy. // The second loop will also map even iterations to T1 // and odd iterations to T2. However, because the second // loop indexes "a" with "i+1", the even iterations, the // ones executed by T1, will add the uninitialized odd // elements of T1's copy of "a" to sum. This behavior // differs from what would happen in sequential mode. #pragma omp parallel for for (i = 0; i < 1000; i++) { a[i] = i; } #pragma omp parallel for reduction (+:sum) for (i = 0; i < 1000; i++) { if (i!=999) sum = sum + a[i+1]; // inconsistent index } printf("%d\n", sum); return 0; }
Copyright © 2010, Intel Corporation. All rights reserved.