1*404b540aSrobert! { dg-do run } 2*404b540aSrobert! { dg-options "-ffixed-form" } 3*404b540aSrobert REAL FUNCTION FN1(I) 4*404b540aSrobert INTEGER I 5*404b540aSrobert FN1 = I * 2.0 6*404b540aSrobert RETURN 7*404b540aSrobert END FUNCTION FN1 8*404b540aSrobert 9*404b540aSrobert REAL FUNCTION FN2(A, B) 10*404b540aSrobert REAL A, B 11*404b540aSrobert FN2 = A + B 12*404b540aSrobert RETURN 13*404b540aSrobert END FUNCTION FN2 14*404b540aSrobert 15*404b540aSrobert PROGRAM A18 16*404b540aSrobert INCLUDE "omp_lib.h" ! or USE OMP_LIB 17*404b540aSrobert INTEGER ISYNC(256) 18*404b540aSrobert REAL WORK(256) 19*404b540aSrobert REAL RESULT(256) 20*404b540aSrobert INTEGER IAM, NEIGHBOR 21*404b540aSrobert!$OMP PARALLEL PRIVATE(IAM, NEIGHBOR) SHARED(WORK, ISYNC) NUM_THREADS(4) 22*404b540aSrobert IAM = OMP_GET_THREAD_NUM() + 1 23*404b540aSrobert ISYNC(IAM) = 0 24*404b540aSrobert!$OMP BARRIER 25*404b540aSrobert! Do computation into my portion of work array 26*404b540aSrobert WORK(IAM) = FN1(IAM) 27*404b540aSrobert! Announce that I am done with my work. 28*404b540aSrobert! The first flush ensures that my work is made visible before 29*404b540aSrobert! synch. The second flush ensures that synch is made visible. 30*404b540aSrobert!$OMP FLUSH(WORK,ISYNC) 31*404b540aSrobert ISYNC(IAM) = 1 32*404b540aSrobert!$OMP FLUSH(ISYNC) 33*404b540aSrobert 34*404b540aSrobert! Wait until neighbor is done. The first flush ensures that 35*404b540aSrobert! synch is read from memory, rather than from the temporary 36*404b540aSrobert! view of memory. The second flush ensures that work is read 37*404b540aSrobert! from memory, and is done so after the while loop exits. 38*404b540aSrobert IF (IAM .EQ. 1) THEN 39*404b540aSrobert NEIGHBOR = OMP_GET_NUM_THREADS() 40*404b540aSrobert ELSE 41*404b540aSrobert NEIGHBOR = IAM - 1 42*404b540aSrobert ENDIF 43*404b540aSrobert DO WHILE (ISYNC(NEIGHBOR) .EQ. 0) 44*404b540aSrobert!$OMP FLUSH(ISYNC) 45*404b540aSrobert END DO 46*404b540aSrobert!$OMP FLUSH(WORK, ISYNC) 47*404b540aSrobert RESULT(IAM) = FN2(WORK(NEIGHBOR), WORK(IAM)) 48*404b540aSrobert!$OMP END PARALLEL 49*404b540aSrobert DO I=1,4 50*404b540aSrobert IF (I .EQ. 1) THEN 51*404b540aSrobert NEIGHBOR = 4 52*404b540aSrobert ELSE 53*404b540aSrobert NEIGHBOR = I - 1 54*404b540aSrobert ENDIF 55*404b540aSrobert IF (RESULT(I) .NE. I * 2 + NEIGHBOR * 2) THEN 56*404b540aSrobert CALL ABORT 57*404b540aSrobert ENDIF 58*404b540aSrobert ENDDO 59*404b540aSrobert END PROGRAM A18 60