Skip to main content

PWD010: Incorrect sharing in OpenMP parallel region

Issue

A variable is being incorrectly shared in the OpenMP datascoping clauses.

Actions

Change the data scope of the variable from shared to private.

Relevance

Specifying an invalid scope for a variable may introduce race conditions and produce incorrect results. For instance, when a variable is written from parallel threads and the specified scoping is shared instead of private.

Code example

C

In the following code, no variable is privatized. According to OpenMP's default behavior, the iterator variable i of the outermost loop (where the OpenMP directive is positioned) is automatically privatized for each thread, but the variable j of the innermost loop is incorrectly left as shared among threads:

void example(int **result, unsigned rows, unsigned cols) {
int i, j;

// j is implicitly shared and it should be private!
#pragma omp parallel for shared(result)
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
result[i][j] = 0;
}
}
}

This introduces a data race among threads on the variable j. It should be explicitly privatized with a private clause:

void example(int **result, unsigned rows, unsigned cols) {
int i, j;

#pragma omp parallel for default(none) shared(result) private(i, j)
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
result[i][j] = 0;
}
}
}

Fortran

In the following code, no variable is privatized. According to OpenMP's default behavior, the iterator variable j of the outermost loop (where the OpenMP directive is positioned) is automatically privatized for each thread, but the variable i of the innermost loop is incorrectly left as shared among threads:

subroutine example(result)
integer, intent(out) :: result(:, :)
integer :: i, j

!$omp parallel do shared(result)
do j = 1, size(result, 2)
do i = 1, size(result, 1)
result(i, j) = 0
end do
end do
end subroutine example

This introduces a data race among threads on the variable i. It should be explicitly privatized with a private clause:

subroutine example(result)
integer, intent(out) :: result(:, :)
integer :: i, j

!$omp parallel do default(none) shared(result) private(i, j)
do j = 1, size(result, 2)
do i = 1, size(result, 1)
result(i, j) = 0
end do
end do
end subroutine example

References