The following examples show valid applications of parallel directives.
In Example 11-1, assignment to the context-shared variables SUMA and SUMB must be guarded from multiple processes attempting to write to the variable at the same time. The LOCKON and LOCKOFF directives accomplish this task by ensuring scalar execution of the statements.
CPAR$ PRIVATE I
CPAR$ SHARED /COM1/
CPAR$ CONTEXT_SHARED SUMA, SUMB
COMMON/COM1/A, B
INTEGER A(1000), B(1000), SUMA, SUMB
LOGICAL *4 LCK_VAR
CPAR$ DO_PARALLEL
DO I = 1, 1000
CALL CALCULATE (I)
CPAR$ LOCKON LCK_VAR ! Guard against multiple processes
SUMA = SUMA + A(I) ! writing to the context-shared
SUMB = SUMB + B(I) ! variable at the same time.
CPAR$ LOCKOFF LCK_VAR
ENDDO
PRINT*, 'SUM A=', SUMA
PRINT*, 'SUM B=', SUMB
END
Example 11-2 shows the SHARED, CONTEXT_SHARED, and PRIVATE directives.
INTEGER A(1000), B(100))
COMMON/COM1/B
PARAMETER (N = 1000)
CPAR$ SHARED_ALL ! Reinforces the SHARED default for
! common blocks.
CPAR$ CONTEXT_SHARED_ALL ! Reinforces the CONTEXT_SHARED default
! for local symbols.
CPAR$ PRIVATE I ! Loop control must be private.
CPAR$ DO_PARALLEL
DO 10 I = 1, N
. . .
A(I) = A(I) + I
B(I) = A(I)
. . .
10 CONTINUE
CALL SUBR(A, N)
WRITE (5,*) A, B
END
C
C
SUBROUTINE SUBR(A, N)
INTEGER A(N), B(1000)
COMMON/COM1/B
CPAR$ SHARED /COM1/ ! The common block must be SHARED.
CPAR$ PRIVATE_ALL ! Make the default PRIVATE.
CPAR$ DO_PARALLEL N/2 ! Distributes half of the iterations to
DO J = 1, N ! each of two processors.
. . .
A(J) = B(J) + J
. . .
ENDDO
RETURN
END