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