ordered Clause and ordered Construct
9.8. ordered Clause and ordered Construct#
Ordered constructs are useful for sequentially ordering the output from work that is done in parallel. The following program prints out the indices in sequential order:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: ordered.1
* type: C
*/
#include <stdio.h>
void work(int k)
{
#pragma omp ordered
printf(" %d\n", k);
}
void ordered_example(int lb, int ub, int stride)
{
int i;
#pragma omp parallel for ordered schedule(dynamic)
for (i=lb; i<ub; i+=stride)
work(i);
}
int main()
{
ordered_example(0, 100, 5);
return 0;
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: ordered.1
! type: F-fixed
SUBROUTINE WORK(K)
INTEGER k
!$OMP ORDERED
WRITE(*,*) K
!$OMP END ORDERED
END SUBROUTINE WORK
SUBROUTINE SUB(LB, UB, STRIDE)
INTEGER LB, UB, STRIDE
INTEGER I
!$OMP PARALLEL DO ORDERED SCHEDULE(DYNAMIC)
DO I=LB,UB,STRIDE
CALL WORK(I)
END DO
!$OMP END PARALLEL DO
END SUBROUTINE SUB
PROGRAM ORDERED_EXAMPLE
CALL SUB(1,100,5)
END PROGRAM ORDERED_EXAMPLE
It is possible to have multiple ordered constructs within a loop region with the ordered clause specified. The first example is non-conforming because all iterations execute two ordered regions. An iteration of a loop must not execute more than one ordered region:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: ordered.2
* type: C
*/
void work(int i) {}
void ordered_wrong(int n)
{
int i;
#pragma omp for ordered
for (i=0; i<n; i++) {
/* incorrect because an iteration may not execute more than one
ordered region */
#pragma omp ordered
work(i);
#pragma omp ordered
work(i+1);
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: ordered.2
! type: F-fixed
SUBROUTINE WORK(I)
INTEGER I
END SUBROUTINE WORK
SUBROUTINE ORDERED_WRONG(N)
INTEGER N
INTEGER I
!$OMP DO ORDERED
DO I = 1, N
! incorrect because an iteration may not execute more than one
! ordered region
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
!$OMP ORDERED
CALL WORK(I+1)
!$OMP END ORDERED
END DO
END SUBROUTINE ORDERED_WRONG
The following is a conforming example with more than one ordered construct. Each iteration will execute only one ordered region:
//%compiler: clang
//%cflags: -fopenmp
/*
* name: ordered.3
* type: C
*/
void work(int i) {}
void ordered_good(int n)
{
int i;
#pragma omp for ordered
for (i=0; i<n; i++) {
if (i <= 10) {
#pragma omp ordered
work(i);
}
if (i > 10) {
#pragma omp ordered
work(i+1);
}
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: ordered.3
! type: F-fixed
SUBROUTINE ORDERED_GOOD(N)
INTEGER N
!$OMP DO ORDERED
DO I = 1,N
IF (I <= 10) THEN
!$OMP ORDERED
CALL WORK(I)
!$OMP END ORDERED
ENDIF
IF (I > 10) THEN
!$OMP ORDERED
CALL WORK(I+1)
!$OMP END ORDERED
ENDIF
ENDDO
END SUBROUTINE ORDERED_GOOD