source: CPL/oasis3/trunk/src/lib/clim/src/CLIM_Import.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: 6.9 KB
Line 
1      SUBROUTINE CLIM_Import(id_port_id,kstep,pfield,kinfo)
2c
3c*    *** Import ***   
4c
5c     purpose:
6c     --------
7c        recv pfield from models connected to port id_port_id
8c
9c     interface:
10c     ----------
11c        id_port_id : port number of the field
12c        kstep  : current time in seconds
13c        pfield : buffer of reals
14c        kinfo  : output status
15c
16c     lib mp:
17c     -------
18c        mpi-1
19c
20c     author:
21c     -------
22c        Eric Sevault   - METEO FRANCE
23c        Laurent Terray - CERFACS
24c        Jean Latour    - F.S.E. 
25c        Arnaud Caubel  - Fecit
26c
27c     ----------------------------------------------------------------
28#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
29      USE mod_kinds_oasis
30      USE mod_clim
31      USE mod_comclim
32#include <mpif.h>
33c     ----------------------------------------------------------------
34      INTEGER (kind=ip_intwp_p)       kstep, kinfo
35      CHARACTER(len=1), DIMENSION(*) :: pfield     
36c     ----------------------------------------------------------------
37      INTEGER (kind=ip_intwp_p)     i4kstep
38      INTEGER (kind=ip_intwp_p)     info
39      INTEGER (kind=ip_intwp_p)     irecv, imod, ilk, iseg, is, ilgb,
40     $    itid, itag, ilen, ioff, ityp, ibyt
41      INTEGER (kind=ip_intwp_p)     iposbuf, istatus(MPI_STATUS_SIZE), 
42     $    imaxbyt
43c
44#ifdef __DEBUG
45      INTEGER(kind=ip_intwp_p)     icount
46      INTEGER(kind=ip_intwp_p), parameter :: icountmax=600
47      LOGICAL                      iflag
48#endif
49c     ----------------------------------------------------------------
50c
51c*    0. First Check
52c     --------------
53c
54      i4kstep = kstep
55      istatus(:)=0
56c
57      IF (nexit.ne.1) THEN
58          kinfo = CLIM_FastExit
59          WRITE(nulprt,FMT='(A)') 'Import - should not be called'
60          GO TO 1010
61      ENDIF
62      kinfo = CLIM_Ok
63c
64c*    1. check for this port in my list
65c     ---------------------------------
66c
67      irecv = 0
68      iport = -1
69c
70      IF (myport(1,id_port_id).eq.CLIM_In) iport=id_port_id
71      IF (iport.lt.0) THEN
72         kinfo = CLIM_BadPort
73         WRITE(nulprt,FMT='(A,A)')
74     *         'Import - WARNING - Invalid port out: ', 
75     $        cports(id_port_id)
76         GO TO 1010
77      ENDIF
78c
79c*    2. check for connected ports (in)
80c     ---------------------------------
81c
82      WRITE(nulprt,FMT='(A,A)') 'Import - ', cports(iport)
83c
84      ityp = myport(2,iport)
85      ibyt = myport(3,iport)
86c
87      DO 290 ip=1,myport(5,iport)
88c
89         ilk  = myport(5+ip,iport)
90         imod = mylink(1,ilk)
91         itid = mylink(2,ilk)
92         itag = mylink(3,ilk) - i4kstep / ig_frqmin
93         iseg = mylink(4,ilk)
94c
95c*   Implementation with "blocking" receives : the program will wait
96c*   indefinitely until a message is received (this may generate a
97c*   deadlock if all models are waiting on a receive).
98c*   However this method will be more efficient in most cases than the
99c*   receives with a time-out loop. 
100c
101#ifdef __DEBUG
102c
103c added to detect deadlocks (J. Latour, 2004-04-28)
104c
105         CALL MPI_Iprobe ( itid, itag, mpi_comm, iflag, istatus, info )
106         WRITE(nulprt,*) 'probing for tid = ',itid,' tag = ',itag,
107     *       ' comm = ',mpi_comm,' result is : ',iflag
108         CALL flush(nulprt) 
109
110         IF (.NOT.iflag) THEN
111             icount = 0
112             WAITLOOP:  DO
113             CALL  MPI_Iprobe ( itid, itag, mpi_comm, iflag, istatus, info )
114             icount = icount + 1
115             IF ( iflag ) EXIT WAITLOOP
116             IF ( icount .GE. icountmax ) THEN
117                 WRITE(nulprt,*) 'probing for tid = ',itid,' tag = ',itag,
118     *               ' still negative after ',icountmax,' seconds : Abort the job'
119                 CALL flush(nulprt)
120                 CALL MPI_ABORT (mpi_comm, 0, mpi_err)
121             ENDIF
122             call sleep(1)
123             END DO WAITLOOP
124             WRITE(nulprt,*) 'probing for tid = ',itid,'icount = ', icount
125             call flush(nulprt)
126         ENDIF
127#endif
128            CALL MPI_Recv ( pkwork, ig_maxtype, MPI_PACKED, itid,
129     *                       itag, mpi_comm, istatus, info ) 
130            CALL MPI_Get_count ( istatus, MPI_PACKED, imaxbyt, info )
131c
132            IF ( info .EQ. CLIM_ok  .AND.  imaxbyt .GT. 0) THEN
133               ilgb = 0
134               iposbuf = 0
135               DO 260 is=1,iseg
136                  ioff = mylink(4+2*is-1,ilk) * ibyt + 1
137                  ilen = mylink(4+2*is,ilk)
138c
139c                 IF     ( ityp .EQ. CLIM_Integer ) THEN
140c                     CALL MPI_Unpack ( pkwork, ig_maxtype, iposbuf, 
141c     *                 pfield(ioff), ilen, MPI_INTEGER, mpi_comm,info)
142c                 ELSEIF ( ityp .EQ. CLIM_Real ) THEN
143                  IF ( ityp .EQ. CLIM_Real ) THEN
144C                     IF ( kind(rl_testvar) .eq. 4 ) THEN
145                     IF ( ip_realwp_p .eq. ip_single_p ) THEN
146                         CALL MPI_Unpack ( pkwork, ig_maxtype, iposbuf,
147     *                       pfield(ioff), ilen, MPI_REAL, 
148     *                       mpi_comm, info)
149C                     ELSE IF ( kind(rl_testvar) .eq. 8 ) THEN
150                     ELSE IF ( ip_realwp_p .eq. ip_double_p ) THEN
151                         CALL MPI_Unpack ( pkwork, ig_maxtype, iposbuf,
152     *                       pfield(ioff), ilen, MPI_DOUBLE_PRECISION, 
153     *                       mpi_comm, info)
154                     ENDIF
155c                 ELSEIF ( ityp .EQ. CLIM_Double ) THEN
156c                     CALL MPI_Unpack ( pkwork, ig_maxtype, iposbuf,
157c     *                  pfield(ioff), 
158c     *                  ilen, MPI_DOUBLE_PRECISION, mpi_comm, info)
159                 ELSE
160                     WRITE(nulprt,*)'Import - pb type incorrect ',ityp
161                     kinfo = CLIM_BadType
162                     GO TO 1010
163                 ENDIF
164                 ilgb = ilgb + ilen
165 260           CONTINUE
166               IF (ilgb*ibyt .le. imaxbyt) THEN
167                   irecv  = irecv + 1
168                   nbrecv = nbrecv + ilgb * ibyt
169                   WRITE(nulprt,FMT='(A,I2,A,I9,A,I7,A,I2,A,I10,A)')
170     *                 'Import - <from:',imod,
171     *                 '> <step:',kstep,
172     *                 '> <len:',ilgb,
173     *                 '> <type:',ibyt,
174     *                 '> <tag:',itag,'>'
175               ELSE
176                   kinfo = CLIM_Unpack
177                   WRITE(nulprt,FMT='(A,I3,A)')
178     *                 'Import - pb unpack <mpi ',info,'>'
179               ENDIF
180           ELSE
181               kinfo = CLIM_TimeOut
182               WRITE(nulprt,FMT='(A,I3,A)')
183     *              'Import - abnormal exit from trecv <mpi ',info,'>'
184           ENDIF
185c
186 290  CONTINUE
187c
188      WRITE(nulprt,FMT='(A,I3,A)')
189     *     'Import - ',irecv,' fields imported'
190c
191c     ----------------------------------------------------------------
192c
193 1010 CONTINUE
194      CALL FLUSH(nulprt)
195#endif
196      RETURN
197      END
Note: See TracBrowser for help on using the repository browser.