/[MITgcm]/MITgcm/eesupp/src/barrier.F
ViewVC logotype

Contents of /MITgcm/eesupp/src/barrier.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.5 - (show annotations) (download)
Wed Oct 28 03:11:33 1998 UTC (25 years, 6 months ago) by cnh
Branch: MAIN
CVS Tags: checkpoint17, checkpoint19, checkpoint18, checkpoint20, checkpoint21, checkpoint16
Changes since 1.4: +11 -8 lines
Changes to support
 - g77 compilation under Linux
 - LR(1) form of 64-bit is D or E for constants
 - Modified adjoint of exch with adjoint variables
   acuumulated.

1 C $Header: /u/gcmpack/models/MITgcmUV/eesupp/src/barrier.F,v 1.4 1998/09/29 18:50:56 cnh Exp $
2
3 #include "CPP_EEOPTIONS.h"
4
5 SUBROUTINE BARRIER_INIT
6
7 #include "SIZE.h"
8 #include "EEPARAMS.h"
9 #include "EESUPPORT.h"
10 #include "BARRIER.h"
11
12 C === Local Variables ===
13 INTEGER I
14
15 DO I=1,nThreads
16 key1(1,I) = INVALID
17 key2(1,I) = INVALID
18 key3(1,I) = INVALID
19 door1 = SHUT
20 door2 = SHUT
21 door3 = SHUT
22 ENDDO
23
24 RETURN
25 END
26 SUBROUTINE BARRIER( myThid )
27 IMPLICIT NONE
28 C
29 C /==========================================================\
30 C | SUBROUTINE BARRIER |
31 C | o Barrier routine that uses "busy waiting". |
32 C |==========================================================|
33 C | This routine provides a pure fortran mechanism to |
34 C | synchronise multiple threads in a multi-threaded code. |
35 C | No thread can leave this routine before all the threads |
36 C | have entered it. |
37 C | Notes |
38 C | ===== |
39 C | The door and key variables are assumed to have been |
40 C | initialized once an initial state of key = INVALID |
41 C | and door = SHUT. |
42 C | We use the routine FOOL_THE_COMPILER to stop compilers |
43 C | generating code which might simply set and test a |
44 C | register value. Shared-memory systems only maintain |
45 C | coherency over process caches and not registers. |
46 C | Also we have to be a bit careful regarding sequential |
47 C | consistency - or lack of it. At the moment the code |
48 C | assumes a total store order memory model, which some |
49 C | machines do not have! However, I have yet to find a |
50 C | problem with this I think because the tolerances in |
51 C | terms of memory ordering i.e. a little bit of reordering |
52 C | probably will not break the barrier mechanism! |
53 C | On non-cache coherent systems e.g. T3E we need to use |
54 C | a library function to do barriers. |
55 C | Note - The PANIC tests can be removed for working code |
56 C | I have left them in without an ifdef option |
57 C | because without them programming errors can |
58 C | lead to infinitely spinning code. If you are |
59 C | confident that your code is OK then removing |
60 C | them may increase performance. Do not remove these|
61 C | lines to make your code "work" If the code is |
62 C | stopping in these PANIC blocks then something is |
63 C | wrong with your program and it needs to be fixed. |
64 C \==========================================================/
65
66 #include "SIZE.h"
67 #include "EEPARAMS.h"
68 #include "EESUPPORT.h"
69 #include "BARRIER.h"
70
71 C === Routine arguments ===
72 INTEGER myThid
73
74 C === Local variables ===
75 C nDone - Counter for number of threads that have
76 C completed a section.
77 C I - Loop counter
78 INTEGER nDone
79 INTEGER I
80
81 CcnhDebugStarts
82 C WRITE(myThid,*) ' Barrier entered '
83 CcnhDebugEnds
84
85 C-- Check that thread number is expected range
86 IF ( myThid .LT. 1 .OR. myThid .GT. nThreads ) THEN
87 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
88 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
89 & myThid, ' nThreads = ', nThreads
90 STOP 'ABNROMAL END: S/R BARRIER'
91 ENDIF
92
93 C-- When every threads key1 is valid thread 1 will open door1.
94 IF ( key1(1,myThid) .EQ. VALID ) THEN
95 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
96 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
97 & myThid, ' key1 already validated'
98 STOP 'ABNROMAL END: S/R BARRIER'
99 ENDIF
100 key1(1,myThid) = VALID
101
102 IF ( myThid .eq. 1 ) THEN
103 10 CONTINUE
104 nDone = 0
105 DO I=1,nThreads
106 if ( key1(1,I) .EQ. VALID ) nDone = nDone+1
107 ENDDO
108 CALL FOOL_THE_COMPILER( key1 )
109 IF ( nDone .LT. nThreads ) GOTO 10
110 door1 = OPEN
111 ELSE
112 11 CONTINUE
113 CALL FOOL_THE_COMPILER( door1 )
114 IF ( door1 .NE. OPEN ) GOTO 11
115 ENDIF
116 C-- Invalidate keys for door1 here as it is now open
117 key1(1,myThid) = INVALID
118
119 CcnhDebugStarts
120 C IF ( myThid .EQ. 1 ) THEN
121 C WRITE(0,*) ' DOOR1 Opened '
122 C ENDIF
123 CcnhDebugEnds
124
125 C-- I can now shut door3 because I know everyone has reached
126 C-- door1. I can't shut door1 because I don't know if everyone
127 C-- has "gone" through the door yet. Nobody has yet reached
128 C-- door3 because they have to go through door2 first.
129 IF ( myThid .EQ. 1 ) THEN
130 door3 = SHUT
131 ENDIF
132
133 C-- When every threads key2 is valid thread 1 will open door2.
134 C Notes
135 C =====
136 C I think that to work with any memory model ( i.e. relaxed,
137 C partial store, total store) the variables key1, key2 and key3
138 C might need to be set to invalid by thread 1.
139 C
140 IF ( key2(1,myThid) .EQ. VALID ) THEN
141 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
142 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
143 & myThid, ' key2 already validated'
144 STOP 'ABNROMAL END: S/R BARRIER'
145 ENDIF
146 key2(1,myThid) = VALID
147 C
148 IF ( myThid .eq. 1 ) THEN
149 20 CONTINUE
150 nDone = 0
151 DO I=1,nThreads
152 if ( key2(1,I) .EQ. VALID ) nDone = nDone+1
153 ENDDO
154 CALL FOOL_THE_COMPILER( key2 )
155 IF ( nDone .LT. nThreads ) GOTO 20
156 door2 = OPEN
157 ELSE
158 21 CONTINUE
159 CALL FOOL_THE_COMPILER( door2 )
160 IF ( door2 .NE. OPEN ) GOTO 21
161 ENDIF
162
163 C-- Invalidate keys for door2 here as it is now open
164 key2(1,myThid) = INVALID
165
166 C-- I can now shut door1 because I know everyone has reached
167 C-- door2. I can't shut door2 because I don't know if everyone
168 C-- has "gone" through the door yet. Nobody has yet reached
169 C-- door1 because they have to go through door3 first.
170 IF ( myThid .EQ. 1 ) THEN
171 door1 = SHUT
172 ENDIF
173
174
175 C-- When every threads key3 is valid thread 1 will open door3.
176 IF ( key3(1,myThid) .EQ. VALID ) THEN
177 WRITE(0,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
178 WRITE(0,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
179 & myThid, ' key3 already validated'
180 STOP 'ABNROMAL END: S/R BARRIER'
181 ENDIF
182 key3(1,myThid) = VALID
183 C
184 IF ( myThid .eq. 1 ) THEN
185 30 CONTINUE
186 nDone = 0
187 DO I=1,nThreads
188 if ( key3(1,I) .EQ. VALID ) nDone = nDone+1
189 ENDDO
190 CALL FOOL_THE_COMPILER( key3 )
191 IF ( nDone .LT. nThreads ) GOTO 30
192 door3 = OPEN
193 ELSE
194 31 CONTINUE
195 CALL FOOL_THE_COMPILER( door3 )
196 IF ( door3 .NE. OPEN ) GOTO 31
197 ENDIF
198
199 C-- Invalidate keys for door3 here as it is now open
200 key3(1,myThid) = INVALID
201
202 C-- I can now shut door2 because I know everyone has reached
203 C-- door3. I can't shut door3 because I don't know if everyone
204 C-- has "gone" through the door yet. Nobody has yet reached
205 C-- door2 because they have to go through door1 first.
206 IF ( myThid .EQ. 1 ) THEN
207 door2 = SHUT
208 ENDIF
209
210 CcnhDebugStarts
211 C WRITE(myThid,*) ' Barrier exited '
212 CcnhDebugEnds
213
214 RETURN
215 END

  ViewVC Help
Powered by ViewVC 1.1.22