An OpenMP* REDUCTION variable is accessed outside of region.
In OpenMP*, a REDUCTION clause effectively replaces references to the named variable with references to a thread-private copy. This renaming is only effective inside the OpenMP construct containing the REDUCTION clause. If control transfers out of the construct through a procedure call, and that procedure accesses the same variable name, then this renaming will not be effective. Thhe procedure will access the outer variable, not the temporary. This defeats the intent of the REDUCTION clause and causes the program to behave differently in parallel and sequential mode.
Another way to look at this is that the REDUCTION clause is only effective within the static scope of the OpenMP construct, but it really needs to be in effect within the entire dynamic extent.
It is possible to access a REDUCTION 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 REDUCTION clause |
2 |
Memory write |
The place the REDUCTION variable was assigned |
#include <stdio.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 // marked as a reduction variable void mysub() { k++; } int main(int argc, char **argv) { int i; #pragma omp parallel for reduction(+:k) for (i = 0; i < 1000; i++) { mysub(); k++; } return 0; }
Copyright © 2010, Intel Corporation. All rights reserved.