/[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.13 - (show annotations) (download)
Tue Nov 8 15:53:41 2005 UTC (18 years, 6 months ago) by cnh
Branch: MAIN
CVS Tags: checkpoint58b_post, checkpoint57y_post, checkpoint59, checkpoint58, checkpoint58f_post, checkpoint58d_post, checkpoint58a_post, checkpoint57z_post, checkpoint58y_post, checkpoint58t_post, checkpoint58m_post, checkpoint60, checkpoint61, checkpoint58w_post, checkpoint57y_pre, checkpoint58o_post, checkpoint58p_post, checkpoint58q_post, checkpoint58e_post, mitgcm_mapl_00, checkpoint58r_post, checkpoint58n_post, checkpoint59q, checkpoint59p, checkpoint59r, checkpoint59e, checkpoint59d, checkpoint59g, checkpoint59f, checkpoint59a, checkpoint59c, checkpoint59b, checkpoint59m, checkpoint59l, checkpoint59o, checkpoint59n, checkpoint59i, checkpoint59h, checkpoint59k, checkpoint58k_post, checkpoint58v_post, checkpoint58l_post, checkpoint61f, checkpoint58g_post, checkpoint58x_post, checkpoint61n, checkpoint59j, checkpoint58h_post, checkpoint58j_post, checkpoint61q, checkpoint61e, checkpoint58i_post, checkpoint57x_post, checkpoint58c_post, checkpoint58u_post, checkpoint58s_post, checkpoint61g, checkpoint61d, checkpoint61b, checkpoint61c, checkpoint61a, checkpoint61o, checkpoint61l, checkpoint61m, checkpoint61j, checkpoint61k, checkpoint61h, checkpoint61i, checkpoint61t, checkpoint61r, checkpoint61s, checkpoint61p
Changes since 1.12: +38 -1 lines
Changes toward getting exf working multi-threaded.
  o added some opitonal consistency check in barrier for
    trapping barrier calls in singel threaded region
  o removed a single thread block in ini_depths - singleCpuIO
    still broken.
  o modified parts of exf_ that were setting local stack variables
    in single threaded section and then referencing them from all
    threads.
  o commented out strange stop in mdsio for multithreading which
    seems uneeded.
  o fixed ptracers initialization and changed ptracers monitor
    to avoid race condition in which several threads set a shared
    logical flag at arbitrary moments with respect to each other

1 C $Header: /u/gcmpack/MITgcm/eesupp/src/barrier.F,v 1.12 2005/11/07 18:16:08 cnh Exp $
2 C $Name: $
3
4 #include "CPP_EEOPTIONS.h"
5
6 CBOP
7 C !ROUTINE: BARRIER_INIT
8
9 C !INTERFACE:
10 SUBROUTINE BARRIER_INIT
11 IMPLICIT NONE
12
13 C !DESCRIPTION:
14 C *=====================================================================*
15 C | SUBROUTINE BARRIER\_INIT
16 C | o Setup global barrier data structures.
17 C *=====================================================================*
18 C | Initialise global barrier data structures that can be used in
19 C | conjunction with MPI or that can also be used to create
20 C *=====================================================================*
21
22 C !USES:
23 C == Global variables ==
24 #include "SIZE.h"
25 #include "EEPARAMS.h"
26 #include "EESUPPORT.h"
27 #include "BARRIER.h"
28
29 C !LOCAL VARIABLES:
30 C == Local Variables ==
31 C I :: Loop counter
32 INTEGER I
33 CEOP
34
35 DO I=1,nThreads
36 key1(1,I) = INVALID
37 key2(1,I) = INVALID
38 key3(1,I) = INVALID
39 door1 = SHUT
40 door2 = SHUT
41 door3 = SHUT
42 bCount(I) = 0
43 masterSet(I) = 0
44 ENDDO
45
46 RETURN
47 END
48
49 CBOP
50 C !ROUTINE: BARRIER
51
52 C !INTERFACE:
53 SUBROUTINE BARRIER( myThid )
54 IMPLICIT NONE
55
56 C !DESCRIPTION:
57 C *==========================================================*
58 C | SUBROUTINE BARRIER
59 C | o Barrier routine that uses "busy waiting".
60 C *==========================================================*
61 C | This routine provides a pure fortran mechanism to
62 C | synchronise multiple threads in a multi-threaded code.
63 C | No thread can leave this routine before all the threads
64 C | have entered it.
65 C | Notes
66 C | =====
67 C | The door and key variables are assumed to have been
68 C | initialized once an initial state of key = INVALID
69 C | and door = SHUT.
70 C | We use the routine FOOL\_THE\_COMPILER to stop compilers
71 C | generating code which might simply set and test a
72 C | register value. Shared-memory systems only maintain
73 C | coherency over process caches and not registers.
74 C | Also we have to be a bit careful regarding sequential
75 C | consistency - or lack of it. At the moment the code
76 C | assumes a total store order memory model, which some
77 C | machines do not have! However, I have yet to find a
78 C | problem with this I think because the tolerances in
79 C | terms of memory ordering i.e. a little bit of reordering
80 C | probably will not break the barrier mechanism!
81 C | On non-cache coherent systems e.g. T3E we need to use
82 C | a library function to do barriers.
83 C | Note - The PANIC tests can be removed for working code
84 C | I have left them in without an ifdef option
85 C | because without them programming errors can
86 C | lead to infinitely spinning code. If you are
87 C | confident that your code is OK then removing
88 C | them may increase performance. Do not remove these
89 C | lines to make your code "work" If the code is
90 C | stopping in these PANIC blocks then something is
91 C | wrong with your program and it needs to be fixed.
92 C *==========================================================*
93
94 C !USES:
95 C == Global variables ==
96 #include "SIZE.h"
97 #include "EEPARAMS.h"
98 #include "EESUPPORT.h"
99 #include "BARRIER.h"
100
101 C !INPUT PARAMETERS:
102 C == Routine arguments ==
103 INTEGER myThid
104
105 C !LOCAL VARIABLES:
106 C === Local variables ===
107 C nDone :: Counter for number of threads that have
108 C completed a section.
109 C I :: Loop counter
110 INTEGER nDone
111 INTEGER I
112 CEOP
113
114 CcnhDebugStarts
115 C WRITE(myThid,*) ' Barrier entered '
116 CcnhDebugEnds
117
118 #ifdef USE_OMP_THREADING
119 C$OMP BARRIER
120 bCount(myThid) = bCount(myThid) + 1
121 IF ( masterSet(myThid) .NE. 0 ) THEN
122 PRINT *, 'BARRIER called for master reg myThid == ',
123 & myThid, masterSet(myThid)
124 ENDIF
125 Cdbg C$OMP BARRIER
126 Cdbg DO I=2, nThreads
127 Cdbg IF (bCount(I) .NE. bCount(1) ) THEN
128 Cdbg PRINT *, bCount(1:nThreads)
129 Cdbg CALL SYSTEM('sleep 1')
130 Cdbg PRINT *, bCount(1:nThreads)
131 Cdbg PRINT *, bCount(1:nThreads)
132 Cdbg PRINT *, bCount(1:nThreads)
133 Cdbg PRINT *, bCount(1:nThreads)
134 Cdbg STOP ' barrier out of sync '
135 Cdbg ENDIF
136 Cdbg ENDDO
137 Cdbg C$OMP BARRIER
138 RETURN
139 #endif
140
141 C-- Check that thread number is expected range
142 IF ( myThid .LT. 1 .OR. myThid .GT. nThreads ) THEN
143 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
144 WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
145 & myThid, ' nThreads = ', nThreads
146 STOP 'ABNROMAL END: S/R BARRIER'
147 ENDIF
148
149 C-- When every threads key1 is valid thread 1 will open door1.
150 IF ( key1(1,myThid) .EQ. VALID ) THEN
151 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
152 WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
153 & myThid, ' key1 already validated'
154 STOP 'ABNROMAL END: S/R BARRIER'
155 ENDIF
156 key1(1,myThid) = VALID
157
158 IF ( myThid .eq. 1 ) THEN
159 10 CONTINUE
160 nDone = 0
161 DO I=1,nThreads
162 if ( key1(1,I) .EQ. VALID ) nDone = nDone+1
163 ENDDO
164 CALL FOOL_THE_COMPILER( key1 )
165 IF ( nDone .LT. nThreads ) GOTO 10
166 door1 = OPEN
167 ELSE
168 11 CONTINUE
169 CALL FOOL_THE_COMPILER( door1 )
170 IF ( door1 .NE. OPEN ) GOTO 11
171 ENDIF
172 C-- Invalidate keys for door1 here as it is now open
173 key1(1,myThid) = INVALID
174
175 CcnhDebugStarts
176 C IF ( myThid .EQ. 1 ) THEN
177 C WRITE(*,*) ' DOOR1 Opened '
178 C ENDIF
179 CcnhDebugEnds
180
181 C-- I can now shut door3 because I know everyone has reached
182 C-- door1. I can not shut door1 because I do not know if everyone
183 C-- has "gone" through the door yet. Nobody has yet reached
184 C-- door3 because they have to go through door2 first.
185 IF ( myThid .EQ. 1 ) THEN
186 door3 = SHUT
187 ENDIF
188
189 C-- When every threads key2 is valid thread 1 will open door2.
190 C Notes
191 C =====
192 C I think that to work with any memory model ( i.e. relaxed,
193 C partial store, total store) the variables key1, key2 and key3
194 C might need to be set to invalid by thread 1.
195 C
196 IF ( key2(1,myThid) .EQ. VALID ) THEN
197 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
198 WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
199 & myThid, ' key2 already validated'
200 STOP 'ABNROMAL END: S/R BARRIER'
201 ENDIF
202 key2(1,myThid) = VALID
203 C
204 IF ( myThid .eq. 1 ) THEN
205 20 CONTINUE
206 nDone = 0
207 DO I=1,nThreads
208 if ( key2(1,I) .EQ. VALID ) nDone = nDone+1
209 ENDDO
210 CALL FOOL_THE_COMPILER( key2 )
211 IF ( nDone .LT. nThreads ) GOTO 20
212 door2 = OPEN
213 ELSE
214 21 CONTINUE
215 CALL FOOL_THE_COMPILER( door2 )
216 IF ( door2 .NE. OPEN ) GOTO 21
217 ENDIF
218
219 C-- Invalidate keys for door2 here as it is now open
220 key2(1,myThid) = INVALID
221
222 C-- I can now shut door1 because I know everyone has reached
223 C-- door2. I can not shut door2 because I do not know if everyone
224 C-- has "gone" through the door yet. Nobody has yet reached
225 C-- door1 because they have to go through door3 first.
226 IF ( myThid .EQ. 1 ) THEN
227 door1 = SHUT
228 ENDIF
229
230
231 C-- When every threads key3 is valid thread 1 will open door3.
232 IF ( key3(1,myThid) .EQ. VALID ) THEN
233 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
234 WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
235 & myThid, ' key3 already validated'
236 STOP 'ABNROMAL END: S/R BARRIER'
237 ENDIF
238 key3(1,myThid) = VALID
239 C
240 IF ( myThid .eq. 1 ) THEN
241 30 CONTINUE
242 nDone = 0
243 DO I=1,nThreads
244 if ( key3(1,I) .EQ. VALID ) nDone = nDone+1
245 ENDDO
246 CALL FOOL_THE_COMPILER( key3 )
247 IF ( nDone .LT. nThreads ) GOTO 30
248 door3 = OPEN
249 ELSE
250 31 CONTINUE
251 CALL FOOL_THE_COMPILER( door3 )
252 IF ( door3 .NE. OPEN ) GOTO 31
253 ENDIF
254
255 C-- Invalidate keys for door3 here as it is now open
256 key3(1,myThid) = INVALID
257
258 C-- I can now shut door2 because I know everyone has reached
259 C-- door3. I can not shut door3 because I do not know if everyone
260 C-- has "gone" through the door yet. Nobody has yet reached
261 C-- door2 because they have to go through door1 first.
262 IF ( myThid .EQ. 1 ) THEN
263 door2 = SHUT
264 ENDIF
265
266 CcnhDebugStarts
267 C WRITE(myThid,*) ' Barrier exited '
268 CcnhDebugEnds
269
270 RETURN
271 END
272
273 CBOP
274 SUBROUTINE BARRIER_MS( myThid )
275 IMPLICIT NONE
276
277 C !USES:
278 C == Global variables ==
279 #include "SIZE.h"
280 #include "EEPARAMS.h"
281 #include "EESUPPORT.h"
282 #include "BARRIER.h"
283 INTEGER myThid
284
285 masterSet(myThid) = masterSet(myThid) + 1
286
287 RETURN
288 END
289 SUBROUTINE BARRIER_MU( myThid )
290 IMPLICIT NONE
291
292 C !USES:
293 C == Global variables ==
294 #include "SIZE.h"
295 #include "EEPARAMS.h"
296 #include "EESUPPORT.h"
297 #include "BARRIER.h"
298 INTEGER myThid
299
300 masterSet(myThid) = masterSet(myThid) - 1
301
302 RETURN
303 END

  ViewVC Help
Powered by ViewVC 1.1.22