Nested Loop Constructs
12.8. Nested Loop Constructs#
The following example of loop construct nesting is conforming because the inner and outer loop regions bind to different parallel regions:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nested_loop.1
* type: C
*/
void work(int i, int j) {}
void good_nesting(int n)
{
int i, j;
#pragma omp parallel default(shared)
{
#pragma omp for
for (i=0; i<n; i++) {
#pragma omp parallel shared(i, n)
{
#pragma omp for
for (j=0; j < n; j++)
work(i, j);
}
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nested_loop.1
! type: F-fixed
SUBROUTINE WORK(I, J)
INTEGER I, J
END SUBROUTINE WORK
SUBROUTINE GOOD_NESTING(N)
INTEGER N
INTEGER I
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
DO I = 1, N
!$OMP PARALLEL SHARED(I,N)
!$OMP DO
DO J = 1, N
CALL WORK(I,J)
END DO
!$OMP END PARALLEL
END DO
!$OMP END PARALLEL
END SUBROUTINE GOOD_NESTING
The following variation of the preceding example is also conforming:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: nested_loop.2
* type: C
*/
void work(int i, int j) {}
void work1(int i, int n)
{
int j;
#pragma omp parallel default(shared)
{
#pragma omp for
for (j=0; j<n; j++)
work(i, j);
}
}
void good_nesting2(int n)
{
int i;
#pragma omp parallel default(shared)
{
#pragma omp for
for (i=0; i<n; i++)
work1(i, n);
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: nested_loop.2
! type: F-fixed
SUBROUTINE WORK(I, J)
INTEGER I, J
END SUBROUTINE WORK
SUBROUTINE WORK1(I, N)
INTEGER J
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
DO J = 1, N
CALL WORK(I,J)
END DO
!$OMP END PARALLEL
END SUBROUTINE WORK1
SUBROUTINE GOOD_NESTING2(N)
INTEGER N
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
DO I = 1, N
CALL WORK1(I, N)
END DO
!$OMP END PARALLEL
END SUBROUTINE GOOD_NESTING2