source: CPL/oasis3/trunk/src/lib/clim/src/CLIM_Start_MPI.F @ 1677

Last change on this file since 1677 was 1677, checked in by aclsce, 12 years ago

Imported oasis3 (tag ipslcm5a) from cvs server to svn server (igcmg project).

File size: 13.1 KB
Line 
1      SUBROUTINE CLIM_Start_MPI(kinfo)
2c
3c*    *** Start-mpi ***   CLIM 3.0
4c
5c     purpose:
6c     --------
7c        beginning of the coupled run (MPI-2 only)
8c
9c     interface:
10c     ----------
11c        kinfo  : output status
12c
13c     method:
14c     -------
15c        With MPI2, use the new intra-communicator created by the
16c                   MPI_Intercomm_merge in CLIM_Init (models)
17c                   or in inicmc via CLIM_Init (coupler Oasis)
18c
19c     lib mp:
20c     -------
21c        mpi-1 (or mpi-2)
22c
23c     author:
24c     -------
25c        Eric Sevault   - METEO FRANCE
26c        Laurent Terray - CERFACS
27c        Jean Latour    - F.S.E.   (mpi-2)
28c        Sophie Valcke  - CERFACS (08/09/00 -modified)
29c        Arnaud Caubel  - FECIT (08/02 - removed kmxtag as argument)
30c
31c     ----------------------------------------------------------------
32#if defined use_comm_MPI1 || defined use_comm_MPI2 || !defined use_comm_MPI1 && !defined use_comm_MPI2 && !defined use_comm_SIPC && !defined use_comm_GMEM && !defined use_comm_PIPE && !defined use_comm_NONE
33      USE mod_kinds_oasis
34      USE mod_clim 
35      USE mod_comclim
36#include <mpif.h>
37c     ----------------------------------------------------------------
38      INTEGER (kind=ip_intwp_p) kinfo
39c     ----------------------------------------------------------------
40      INTEGER (kind=ip_intwp_p)    ip, info1, info, ilgdt, ipos, is,
41     $    itag1, isdmod, incp, ipotag,nsegid
42      INTEGER (kind=ip_intwp_p)    irempo, il_maxtag
43c
44      INTEGER (kind=ip_intwp_p), PARAMETER ::    ibuflen=3
45      INTEGER (kind=ip_intwp_p)    iposbuf, ibuff_mpi(ibuflen) 
46      INTEGER (kind=ip_intwp_p)    istatus(MPI_STATUS_SIZE), imaxbyt
47      REAL (kind=ip_realwp_p) rl_testvar
48      LOGICAL      ll_flag
49      INTEGER (kind=ip_intwp_p), allocatable :: ireq(:)
50      INTEGER (kind=ip_intwp_p)              :: ireqrecv
51      INTEGER (kind=ip_intwp_p)              :: irc
52      INTEGER (kind=ip_intwp_p)              :: rpkwork(ig_CLIMmax)
53c     ----------------------------------------------------------------
54c
55c
56c     0. define some variables 
57c     ------------------------
58c
59      WRITE(nulprt,*)'Start - -  '
60c           
61      nexit  = 0
62      istatus(:)=0
63      ibuff_mpi(:)=0
64      rl_testvar=0.0_ip_realwp_p
65c
66      call MPI_Attr_get(MPI_COMM_WORLD, MPI_TAG_UB, CLIM_MaxTag, 
67     $    ll_flag,info)
68      if(info.ne.MPI_SUCCESS) then
69        write(nulprt, * )'CLIM_Start_MPI -- MPI_Attr_get failed !',info
70        call MPI_ABORT (mpi_comm, 0, info)
71      endif
72      if ( .not. ll_flag ) then
73         write(nulprt, * ) 'Warning:  MPI_Attr_get did not return '
74         write(nulprt, * ) ' a valid CLIM_MaxTag!'
75         write(nulprt, * ) ' CLIM_MaxTag is set to 32767!'
76         CLIM_MaxTag = 32767
77      else
78         write(nulprt, * ) 'CLIM_MaxTag is now ', CLIM_MaxTag
79!
80!     limit CLIM_MaxTag to 2^^30 - 1 (J. Latour)
81!
82         if ( CLIM_MaxTag .gt. 1073741823 ) CLIM_MaxTag =  1073741823
83         write(nulprt, * ) 'CLIM_MaxTag is now ', CLIM_MaxTag
84!
85      endif
86      il_maxtag = CLIM_MaxTag - 1
87      itag1 = CLIM_MaxTag
88      ilgdt = CLIM_ParSize
89C
90      ig_maxtype = ig_CLIMmax*kind(rl_testvar)
91C
92c*    1. broadcast usefull informations
93c     ---------------------------------
94c
95      ibuff_mpi(1) = mynum 
96      ibuff_mpi(2) = modtid(mynum) 
97      ibuff_mpi(3) = nports
98c
99      WRITE(nulprt,FMT='(A,A)') 'Start- send- MODEL ',cmynam
100      WRITE(nulprt,FMT='(A,I9)')'Start- send-  num  :',mynum
101      WRITE(nulprt,FMT='(A,I9)')'Start- send-  tid  :',modtid(mynum)
102      WRITE(nulprt,FMT='(A,I9)')'Start- send-  nport:',nports
103c
104      iposbuf = 0
105      call MPI_Pack ( ibuff_mpi, ibuflen, MPI_INTEGER, pkwork,
106     *                ig_maxtype, iposbuf, mpi_comm, info )
107      call MPI_Pack ( cmynam, CLIM_Clength, MPI_CHARACTER, pkwork,
108     *                ig_maxtype, iposbuf, mpi_comm, info )
109      DO 210 ji=1,nports
110         call MPI_Pack ( cports(ji), CLIM_Clength, MPI_CHARACTER,
111     *           pkwork, ig_maxtype, iposbuf, mpi_comm, info )
112         call MPI_Pack ( myport(1,ji), 5, MPI_INTEGER, pkwork,
113     *                   ig_maxtype, iposbuf, mpi_comm, info )
114         call MPI_Pack ( mydist(1,ji), ilgdt, MPI_INTEGER, pkwork,
115     *                   ig_maxtype, iposbuf, mpi_comm, info )
116 210   CONTINUE
117c
118       ALLOCATE(ireq(0:ncplprocs))
119       irc = 0
120c
121      DO 220 ji = 0 , ncplprocs-1
122c
123c       Send to all processors involved in the coupling except itself
124c*      This MPI_Send may cause deadlocks, IF your mailbox size is not
125c*      large enough; in that case the size of the mailbox should be 
126c*      increased.
127        IF ( ji .NE. mynum ) THEN
128            CALL MPI_Isend ( pkwork, iposbuf, MPI_PACKED, modtid(ji),
129     *                      itag1, mpi_comm, ireq(irc), info )
130          irc = irc+1
131c
132        ENDIF
133 220  CONTINUE
134
135      WRITE (nulprt,FMT='(A,I3,A,I8,A)') 
136     * 'Start - broadcast from mynum = ',mynum,' <MPI ',info,'>'
137c
138c*    3. get these infos from other models and check ports
139c     ----------------------------------------------------
140c
141      imaxbyt=0
142      ireqrecv=0
143      DO 380 ip=1,ncplprocs-1
144c
145c Blocking receive (to comment if use of non-blocking receive)
146        CALL MPI_Irecv(rpkwork, ig_maxtype, MPI_PACKED, MPI_ANY_SOURCE,
147     *                 itag1, mpi_comm, ireqrecv, info1 )
148        CALL MPI_Wait ( ireqrecv, istatus, info )
149        CALL MPI_Get_count ( istatus, MPI_PACKED, imaxbyt, info )
150        IF ( info .NE. 0 ) THEN
151            kinfo = CLIM_Unpack
152            WRITE(nulprt,FMT='(A,I3,A)')
153     *                 'Import - pb unpack <mpi ',info,'>'
154            GO TO 1010
155        ENDIF
156c END of blocking receive
157c
158c       
159        iposbuf = 0
160        CALL MPI_Unpack ( rpkwork, ig_maxtype, iposbuf, ibuff_mpi,
161     *                      ibuflen, MPI_INTEGER, mpi_comm, info )
162        IF ( info .NE. 0 ) THEN
163            kinfo = CLIM_Unpack
164            WRITE(nulprt,FMT='(A,I3,A)')
165     *                 'Import - pb unpack <mpi ',info,'>'
166            GO TO 1010
167        ENDIF
168c
169        isdmod         = ibuff_mpi(1)
170        modtid(isdmod) = ibuff_mpi(2)
171        irempo         = ibuff_mpi(3)
172c
173        call MPI_Unpack ( rpkwork, ig_maxtype, iposbuf, cnames(isdmod),
174     *                   CLIM_Clength, MPI_CHARACTER, mpi_comm, info )
175        DO 310 ji=1,irempo
176          call MPI_Unpack ( rpkwork, ig_maxtype, iposbuf, clrport(ji),
177     *                   CLIM_Clength, MPI_CHARACTER, mpi_comm, info )
178          call MPI_Unpack( rpkwork, ig_maxtype, iposbuf, irport(1,ji), 
179     *                           5, MPI_INTEGER, mpi_comm, info )
180          call MPI_Unpack( rpkwork, ig_maxtype, iposbuf, irdist(1,ji),
181     *                           ilgdt, MPI_INTEGER, mpi_comm, info )
182 310    CONTINUE
183c
184        WRITE (nulprt,FMT='(A,A)')  'Start - MODEL ',cnames(isdmod)
185        WRITE (nulprt,FMT='(A,I9)') 'Start -   num  :',isdmod
186        WRITE (nulprt,FMT='(A,I9)') 'Start -   tid  :',modtid(isdmod)
187        WRITE (nulprt,FMT='(A,I9)') 'Start -   nport:',irempo
188c
189        ncode(isdmod) = 0
190c
191        DO 350 ji=1,nports
192          DO 340 jj=1,irempo
193            IF (cports(ji).eq.clrport(jj).and.
194     *          myport(1,ji)+irport(1,jj).eq.1) THEN
195                IF ((mydist(1,ji).eq.irdist(1,jj).and.
196     *              myport(4,ji).ne.irport(4,jj)).or.
197     *              (mydist(CLIM_Strategy,ji).eq.CLIM_Serial.and.
198     *              myport(4,ji).lt.irport(4,jj)).or.
199     *              (irdist(CLIM_Strategy,jj).eq.CLIM_Serial.and.
200     *              irport(4,jj).lt.myport(4,ji))) THEN
201                    kinfo = CLIM_IncSize
202                    WRITE(nulprt,FMT='(A,A,A,I2,A,I2,A,I2,I2)')
203     *                  'Start - WARNING Incompatible sizes - field',
204     *                  cports(ji),'model ',mynum,' and model ',
205     *                  isdmod,': ',myport(4,ji),irport(4,jj)
206                ELSEIF (myport(2,ji).ne.irport(2,jj)) THEN
207                    kinfo = CLIM_BadType
208                    WRITE(nulprt,FMT='(A,A,A,I2,A,I2,A,I2,I2)')
209     *                  'Start - WARNING Incompatible types - field',
210     *                  cports(ji),'model ',mynum,' and model ',
211     *                  isdmod,': ',myport(2,ji),irport(2,jj)
212                ELSE
213                    IF (myport(1,ji).eq.CLIM_Out) THEN
214                        incp   = ig_ntime / ig_frqmin + 1
215                        ipotag = CLIM_MaxTag - (ji-1)*incp - 1
216                    ELSE
217                        incp   = ig_ntime / ig_frqmin + 1
218                        ipotag = CLIM_MaxTag - (jj-1)*incp - 1
219                    ENDIF
220                    IF ((ipotag-incp).lt.il_maxtag) THEN
221                        il_maxtag = ipotag - incp
222                    ENDIF
223                    IF (mydist(CLIM_Strategy,ji).ne.CLIM_Serial.and
224     *               .irdist(CLIM_Strategy,jj).ne.CLIM_Serial) THEN
225                        IF (mydist(CLIM_Strategy,ji).ne.
226     *                      irdist(CLIM_Strategy,jj)) THEN
227                            CALL halte('STOP in Clim_Start_MPI')
228                        ELSE
229                            IF (mydist(CLIM_Segments,ji).eq.
230     *                      irdist(CLIM_Segments,jj)) THEN
231                                nsegid = 0                           
232                                DO  is=1,2*mydist(CLIM_Segments,ji)
233                                  IF (mydist(CLIM_Segments+is,ji).eq.
234     *                               irdist(CLIM_Segments+is,jj)) THEN
235                                      nsegid = nsegid + 1
236                                  ENDIF
237                                END DO
238                                IF (nsegid.eq.
239     *                              (2*mydist(CLIM_Segments,ji))) THEN
240                                    nlinks = nlinks + 1
241                                    ipos   = 5
242                                    myport(ipos,ji)=myport(ipos,ji)+ 1
243                                    myport(ipos+myport(ipos,ji),ji)
244     *                                     = nlinks
245                                    mylink(1,nlinks) = isdmod
246                                    mylink(2,nlinks) = modtid(isdmod)
247                                    mylink(3,nlinks) = ipotag
248                                    mylink(4,nlinks) = 1
249                                    mylink(5,nlinks) = 0
250                                    mylink(6,nlinks) = myport(4,ji)
251                                    WRITE(nulprt,FMT='(A,A)')
252     *                                  'Start - LINK ',cports(ji)
253                                    WRITE(nulprt,FMT='(A,I2,A,I1,A,I2,
254     *                                 A,I1,A,I10,A,I10)')
255     *                                  'Start - [model ',
256     *                                  mynum,'/io ',myport(1,ji),'] -
257     *                                    [model ',
258     *                                  isdmod,'/io ',irport(1,jj),']
259     *                                   using tags ',
260     *                                  ipotag,' to ',ipotag-incp+1
261                                ENDIF   
262                            ENDIF
263                        ENDIF
264                    ELSE                   
265                        nlinks = nlinks + 1
266                        ipos   = 5
267                        myport(ipos,ji) = myport(ipos,ji) + 1
268                        myport(ipos+myport(ipos,ji),ji) = nlinks
269                        mylink(1,nlinks) = isdmod
270                        mylink(2,nlinks) = modtid(isdmod)
271                        mylink(3,nlinks) = ipotag
272                        mylink(4,nlinks) = 1
273                        mylink(5,nlinks) = 0
274                        mylink(6,nlinks) = myport(4,ji)
275                        IF (mydist(CLIM_Strategy,ji).eq.CLIM_Serial.and
276     *                   .irdist(CLIM_Strategy,jj).ne.CLIM_Serial) THEN
277                            mylink(4,nlinks) = irdist(CLIM_Segments,jj)
278                            DO 330 is=1,2*irdist(CLIM_Segments,jj)
279                              mylink(4+is,nlinks) = irdist
280     *                                      (CLIM_Segments+is,jj)
281 330                        CONTINUE
282                        ENDIF
283                        WRITE(nulprt,FMT='(A,A)')
284     *                      'Start - LINK ',cports(ji)
285                        WRITE(nulprt,FMT='(A,I2,A,I1,A,I2,A,
286     *                       I1,A,I10,A,I10)')
287     *                      'Start - [model ',
288     *                      mynum,'/io ',myport(1,ji),'] - [model ',
289     *                      isdmod,'/io ',irport(1,jj),'] using tags ',
290     *                      ipotag,' to ',ipotag-incp+1
291                    ENDIF                   
292                ENDIF
293            ENDIF
294 340      CONTINUE
295 350    CONTINUE
296c
297        WRITE (nulprt,FMT='(A)') 'Start - -'
298 380  CONTINUE
299c
300c     MPI_wait on the above MPI_Isend so to not change the content of pkwork
301c     before the sending is complete.
302      irc = 0
303      DO 420 ji = 0 , ncplprocs-1
304        IF ( ji .NE. mynum ) THEN
305            CALL MPI_Wait ( ireq(irc), istatus, info )
306            WRITE (nulprt, FMT='(A)') 'After MPI_wait'
307            irc = irc+1
308        ENDIF
309 420  CONTINUE
310      DEALLOCATE(ireq)
311c
312c*    correct execution
313c
314      nexit = 1
315c
316c     ----------------------------------------------------------------
317c
318 1010 CONTINUE
319      WRITE (nulprt,FMT='(A)') 'Returning from Start-mpi  -- '
320      CALL FLUSH(nulprt)
321#endif
322      RETURN
323      END
Note: See TracBrowser for help on using the repository browser.