1 | SUBROUTINE CLIM_Import(id_port_id,kstep,pfield,kinfo) |
---|
2 | c |
---|
3 | c* *** Import *** |
---|
4 | c |
---|
5 | c purpose: |
---|
6 | c -------- |
---|
7 | c recv pfield from models connected to port id_port_id |
---|
8 | c |
---|
9 | c interface: |
---|
10 | c ---------- |
---|
11 | c id_port_id : port number of the field |
---|
12 | c kstep : current time in seconds |
---|
13 | c pfield : buffer of reals |
---|
14 | c kinfo : output status |
---|
15 | c |
---|
16 | c lib mp: |
---|
17 | c ------- |
---|
18 | c mpi-1 |
---|
19 | c |
---|
20 | c author: |
---|
21 | c ------- |
---|
22 | c Eric Sevault - METEO FRANCE |
---|
23 | c Laurent Terray - CERFACS |
---|
24 | c Jean Latour - F.S.E. |
---|
25 | c Arnaud Caubel - Fecit |
---|
26 | c |
---|
27 | c ---------------------------------------------------------------- |
---|
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> |
---|
33 | c ---------------------------------------------------------------- |
---|
34 | INTEGER (kind=ip_intwp_p) kstep, kinfo |
---|
35 | CHARACTER(len=1), DIMENSION(*) :: pfield |
---|
36 | c ---------------------------------------------------------------- |
---|
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 |
---|
43 | c |
---|
44 | #ifdef __DEBUG |
---|
45 | INTEGER(kind=ip_intwp_p) icount |
---|
46 | INTEGER(kind=ip_intwp_p), parameter :: icountmax=600 |
---|
47 | LOGICAL iflag |
---|
48 | #endif |
---|
49 | c ---------------------------------------------------------------- |
---|
50 | c |
---|
51 | c* 0. First Check |
---|
52 | c -------------- |
---|
53 | c |
---|
54 | i4kstep = kstep |
---|
55 | istatus(:)=0 |
---|
56 | c |
---|
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 |
---|
63 | c |
---|
64 | c* 1. check for this port in my list |
---|
65 | c --------------------------------- |
---|
66 | c |
---|
67 | irecv = 0 |
---|
68 | iport = -1 |
---|
69 | c |
---|
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 |
---|
78 | c |
---|
79 | c* 2. check for connected ports (in) |
---|
80 | c --------------------------------- |
---|
81 | c |
---|
82 | WRITE(nulprt,FMT='(A,A)') 'Import - ', cports(iport) |
---|
83 | c |
---|
84 | ityp = myport(2,iport) |
---|
85 | ibyt = myport(3,iport) |
---|
86 | c |
---|
87 | DO 290 ip=1,myport(5,iport) |
---|
88 | c |
---|
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) |
---|
94 | c |
---|
95 | c* Implementation with "blocking" receives : the program will wait |
---|
96 | c* indefinitely until a message is received (this may generate a |
---|
97 | c* deadlock if all models are waiting on a receive). |
---|
98 | c* However this method will be more efficient in most cases than the |
---|
99 | c* receives with a time-out loop. |
---|
100 | c |
---|
101 | #ifdef __DEBUG |
---|
102 | c |
---|
103 | c added to detect deadlocks (J. Latour, 2004-04-28) |
---|
104 | c |
---|
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 ) |
---|
131 | c |
---|
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) |
---|
138 | c |
---|
139 | c IF ( ityp .EQ. CLIM_Integer ) THEN |
---|
140 | c CALL MPI_Unpack ( pkwork, ig_maxtype, iposbuf, |
---|
141 | c * pfield(ioff), ilen, MPI_INTEGER, mpi_comm,info) |
---|
142 | c ELSEIF ( ityp .EQ. CLIM_Real ) THEN |
---|
143 | IF ( ityp .EQ. CLIM_Real ) THEN |
---|
144 | C 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) |
---|
149 | C 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 |
---|
155 | c ELSEIF ( ityp .EQ. CLIM_Double ) THEN |
---|
156 | c CALL MPI_Unpack ( pkwork, ig_maxtype, iposbuf, |
---|
157 | c * pfield(ioff), |
---|
158 | c * 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 |
---|
185 | c |
---|
186 | 290 CONTINUE |
---|
187 | c |
---|
188 | WRITE(nulprt,FMT='(A,I3,A)') |
---|
189 | * 'Import - ',irecv,' fields imported' |
---|
190 | c |
---|
191 | c ---------------------------------------------------------------- |
---|
192 | c |
---|
193 | 1010 CONTINUE |
---|
194 | CALL FLUSH(nulprt) |
---|
195 | #endif |
---|
196 | RETURN |
---|
197 | END |
---|