An OpenMP* PRIVATE variable is accessed outside the scope of the region.
In OpenMP*, a PRIVATE clause effectively replaces references to the named variable with references to a thread-private copy. This renaming is only effective inside the scope of the OpenMP construct containing the PRIVATE clause. If control transfers out of the construct through a procedure call, and that procedure accesses the same variable name, then the rename will not be effective. That is, the procedure will access the outer variable, not the temporary. This defeats the intent of the PRIVATE clause and causes the program to behave differently in parallel and sequential mode.
Another way to look at this is that the PRIVATE clause is only effective within the static scope of the OpenMP construct, but it really needs to be in effect within the entire dynamic scope.
It is possible to access a PRIVATE variable in a subroutine called from the construct, but only if the variable is accessed via a pointer or a reference parameter. In this case, the reference parameter or pointer will refer to the thread-private temporary. The only rule is that the outer variable must not be accessed by its name in a called subroutine.
ID |
Observation |
Description |
---|---|---|
1 |
OpenMP declaration |
The location of the PRIVATE clause |
2 |
Memory write |
The place the PRIVATE variable was assigned |
#include <stdlib.h> #include <omp.h> int a[1000]; int k = 0; // subroutine accesses k as global variable // can't call this from a region where k is privatized int evilsub(int val) { k = val + 1; return k; } int main(int argc, char **argv) { int i; #pragma omp parallel for firstprivate(k) for (i = 0; i < 1000; i++) { a[i] = evilsub(k); k = k + 2; } return 0; }
Copyright © 2010, Intel Corporation. All rights reserved.