Restrictions on Nesting of Regions
12.9. Restrictions on Nesting of Regions#
The examples in this section illustrate the region nesting rules.
The following example is non-conforming because the inner and outer loop regions are closely nested:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nesting_restrict.1
* type: C
*/
void work(int i, int j) {}
void wrong1(int n)
{
#pragma omp parallel default(shared)
{
int i, j;
#pragma omp for
for (i=0; i<n; i++) {
/* incorrect nesting of loop regions */
#pragma omp for
for (j=0; j<n; j++)
work(i, j);
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nesting_restrict.1
! type: F-fixed
SUBROUTINE WORK(I, J)
INTEGER I, J
END SUBROUTINE WORK
SUBROUTINE WRONG1(N)
INTEGER N
INTEGER I,J
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
DO I = 1, N
!$OMP DO ! incorrect nesting of loop regions
DO J = 1, N
CALL WORK(I,J)
END DO
END DO
!$OMP END PARALLEL
END SUBROUTINE WRONG1
The following orphaned version of the preceding example is also non-conforming:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nesting_restrict.2
* type: C
*/
void work(int i, int j) {}
void work1(int i, int n)
{
int j;
/* incorrect nesting of loop regions */
#pragma omp for
for (j=0; j<n; j++)
work(i, j);
}
void wrong2(int n)
{
#pragma omp parallel default(shared)
{
int i;
#pragma omp for
for (i=0; i<n; i++)
work1(i, n);
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nesting_restrict.2
! type: F-fixed
SUBROUTINE WORK1(I,N)
INTEGER I, N
INTEGER J
!$OMP DO ! incorrect nesting of loop regions
DO J = 1, N
CALL WORK(I,J)
END DO
END SUBROUTINE WORK1
SUBROUTINE WRONG2(N)
INTEGER N
INTEGER I
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
DO I = 1, N
CALL WORK1(I,N)
END DO
!$OMP END PARALLEL
END SUBROUTINE WRONG2
The following example is non-conforming because the loop and single regions are closely nested:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nesting_restrict.3
* type: C
*/
void work(int i, int j) {}
void wrong3(int n)
{
#pragma omp parallel default(shared)
{
int i;
#pragma omp for
for (i=0; i<n; i++) {
/* incorrect nesting of regions */
#pragma omp single
work(i, 0);
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nesting_restrict.3
! type: F-fixed
SUBROUTINE WRONG3(N)
INTEGER N
INTEGER I
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
DO I = 1, N
!$OMP SINGLE ! incorrect nesting of regions
CALL WORK(I, 1)
!$OMP END SINGLE
END DO
!$OMP END PARALLEL
END SUBROUTINE WRONG3
The following example is non-conforming because a barrier region cannot be closely nested inside a loop region:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nesting_restrict.4
* type: C
*/
void work(int i, int j) {}
void wrong4(int n)
{
#pragma omp parallel default(shared)
{
int i;
#pragma omp for
for (i=0; i<n; i++) {
work(i, 0);
/* incorrect nesting of barrier region in a loop region */
#pragma omp barrier
work(i, 1);
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nesting_restrict.4
! type: F-fixed
SUBROUTINE WRONG4(N)
INTEGER N
INTEGER I
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
DO I = 1, N
CALL WORK(I, 1)
! incorrect nesting of barrier region in a loop region
!$OMP BARRIER
CALL WORK(I, 2)
END DO
!$OMP END PARALLEL
END SUBROUTINE WRONG4
The following example is non-conforming because the barrier region cannot be closely nested inside the critical region. If this were permitted, it would result in deadlock due to the fact that only one thread at a time can enter the critical region:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nesting_restrict.5
* type: C
*/
void work(int i, int j) {}
void wrong5(int n)
{
#pragma omp parallel
{
#pragma omp critical
{
work(n, 0);
/* incorrect nesting of barrier region in a critical region */
#pragma omp barrier
work(n, 1);
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nesting_restrict.5
! type: F-fixed
SUBROUTINE WRONG5(N)
INTEGER N
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP CRITICAL
CALL WORK(N,1)
! incorrect nesting of barrier region in a critical region
!$OMP BARRIER
CALL WORK(N,2)
!$OMP END CRITICAL
!$OMP END PARALLEL
END SUBROUTINE WRONG5
The following example is non-conforming because the barrier region cannot be closely nested inside the single region. If this were permitted, it would result in deadlock due to the fact that only one thread executes the single region:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nesting_restrict.6
* type: C
*/
void work(int i, int j) {}
void wrong6(int n)
{
#pragma omp parallel
{
#pragma omp single
{
work(n, 0);
/* incorrect nesting of barrier region in a single region */
#pragma omp barrier
work(n, 1);
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nesting_restrict.6
! type: F-fixed
SUBROUTINE WRONG6(N)
INTEGER N
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP SINGLE
CALL WORK(N,1)
! incorrect nesting of barrier region in a single region
!$OMP BARRIER
CALL WORK(N,2)
!$OMP END SINGLE
!$OMP END PARALLEL
END SUBROUTINE WRONG6