/[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.10 - (show annotations) (download)
Tue May 13 17:23:56 2003 UTC (21 years ago) by adcroft
Branch: MAIN
CVS Tags: checkpoint51k_post, checkpoint52l_pre, hrcube4, hrcube5, checkpoint52d_pre, checkpoint52j_pre, checkpoint51o_pre, checkpoint51l_post, checkpoint52l_post, checkpoint52k_post, checkpoint51, checkpoint52, checkpoint52f_post, checkpoint51f_post, checkpoint51d_post, checkpoint51t_post, checkpoint51n_post, checkpoint52i_pre, hrcube_1, hrcube_2, hrcube_3, checkpoint51s_post, checkpoint51j_post, checkpoint52e_pre, checkpoint52e_post, checkpoint51n_pre, checkpoint52b_pre, checkpoint51l_pre, checkpoint51q_post, checkpoint51b_pre, checkpoint52b_post, checkpoint52c_post, checkpoint51h_pre, checkpoint50f_post, checkpoint50f_pre, checkpoint52f_pre, branchpoint-genmake2, checkpoint51r_post, checkpoint51i_post, checkpoint51b_post, checkpoint51c_post, checkpoint52d_post, checkpoint50g_post, checkpoint52a_pre, checkpoint50h_post, checkpoint52i_post, checkpoint50e_pre, checkpoint50i_post, checkpoint51i_pre, checkpoint52h_pre, checkpoint52j_post, checkpoint50e_post, branch-netcdf, checkpoint51e_post, checkpoint51o_post, checkpoint51f_pre, checkpoint52a_post, checkpoint51g_post, ecco_c52_e35, checkpoint51m_post, checkpoint51a_post, checkpoint51p_post, checkpoint51u_post
Branch point for: branch-genmake2, branch-nonh, tg2-branch, netcdf-sm0, checkpoint51n_branch
Changes since 1.9: +4 -4 lines
Removed quotes in comments
  (luckily, two wrongs make a right so this has not caused
   problems until today for some reason...)

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

  ViewVC Help
Powered by ViewVC 1.1.22