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

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

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


Revision 1.8 - (hide 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 heimbach 1.8 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 cnh 1.1
4     #include "CPP_EEOPTIONS.h"
5    
6     SUBROUTINE BARRIER_INIT
7 adcroft 1.6 IMPLICIT NONE
8 cnh 1.4
9     #include "SIZE.h"
10 cnh 1.1 #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 cnh 1.5 C | machines do not have! However, I have yet to find a |
52 cnh 1.1 C | problem with this I think because the tolerances in |
53     C | terms of memory ordering i.e. a little bit of reordering |
54 cnh 1.5 C | probably will not break the barrier mechanism! |
55 cnh 1.1 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 cnh 1.4
68     #include "SIZE.h"
69 cnh 1.1 #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 cnh 1.3 C WRITE(myThid,*) ' Barrier entered '
85 cnh 1.1 CcnhDebugEnds
86    
87     C-- Check that thread number is expected range
88     IF ( myThid .LT. 1 .OR. myThid .GT. nThreads ) THEN
89 heimbach 1.8 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
90     WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
91 cnh 1.5 & myThid, ' nThreads = ', nThreads
92 cnh 1.1 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 heimbach 1.8 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
98     WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
99 cnh 1.5 & myThid, ' key1 already validated'
100 cnh 1.1 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 heimbach 1.8 C WRITE(*,*) ' DOOR1 Opened '
124 cnh 1.1 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 heimbach 1.8 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
144     WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
145 cnh 1.5 & myThid, ' key2 already validated'
146 cnh 1.1 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 heimbach 1.8 WRITE(*,*) '!!!!!!! PANIC !!!!!!! CATASTROPHIC ERROR'
180     WRITE(*,*) '!!!!!!! PANIC !!!!!!! in S/R BARRIER myThid = ',
181 cnh 1.5 & myThid, ' key3 already validated'
182 cnh 1.1 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 cnh 1.3 C WRITE(myThid,*) ' Barrier exited '
214 cnh 1.1 CcnhDebugEnds
215    
216     RETURN
217     END

  ViewVC Help
Powered by ViewVC 1.1.22