OpenMP* PRIVATE variable accessed outside scope of region

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

Example


#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.