/[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.8 - (show annotations) (download)
Tue Apr 10 22:35:24 2001 UTC (23 years, 1 month ago) by heimbach
Branch: MAIN
CVS Tags: checkpoint40pre3, checkpoint40pre1, checkpoint40pre7, checkpoint40pre6, checkpoint40pre9, checkpoint40pre8, checkpoint38, checkpoint40pre2, checkpoint40pre4, checkpoint39, checkpoint40pre5, checkpoint40
Changes since 1.7: +11 -11 lines
See doc/tag-index and doc/notes_c37_adj.txt
Preparation for stand-alone autodifferentiability.

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

  ViewVC Help
Powered by ViewVC 1.1.22