SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
gather_and_write_mpi_k4.F90
Go to the documentation of this file.
1 !SFX_LIC Copyright 1994-2014 CNRS, Meteo-France and Universite Paul Sabatier
2 !SFX_LIC This is part of the SURFEX software governed by the CeCILL-C licence
3 !SFX_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
4 !SFX_LIC for details. version 1.
6 !----------------------------------------------------
7 !! MODIFICATIONS
8 !! -------------
9 !! Original
10 !! J.Escobar 10/06/2013: replace DOUBLE PRECISION by REAL to handle problem for promotion of real on IBM SP
11 !----------------------------------------------------
12 !
14 !
15 SUBROUTINE gather_and_write_mpi_x1d0(PWORK,PWORK2,KMASK)
16 !
17 REAL, DIMENSION(:), INTENT(IN) :: pwork
18 REAL, DIMENSION(:), INTENT(OUT) :: pwork2
19 !
20 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
21 !
22 END SUBROUTINE gather_and_write_mpi_x1d0
23 !
24 SUBROUTINE gather_and_write_mpi_x2d0(PWORK,PWORK2,KMASK)
25 !
26 REAL, DIMENSION(:,:), INTENT(IN) :: pwork
27 REAL, DIMENSION(:,:), INTENT(OUT) :: pwork2
28 !
29 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
30 !
31 END SUBROUTINE gather_and_write_mpi_x2d0
32 !
33 END INTERFACE
34 !
36 !
37 !**************************************************************************
38 !
39 SUBROUTINE gather_and_write_mpi_x1d0(PWORK,PWORK2,KMASK)
40 !
41 USE modd_surfex_mpi, ONLY : nindex, nproc, nrank, ncomm, npio, nsize, &
42  xtime_comm_write, xtime_calc_write, &
43  xtime_omp_barr, idx_w, wlog_mpi
44 USE modd_surfex_omp, ONLY : nindx1sfx, nindx2sfx, xwork, xwork_full
45 !
46 USE modd_surf_par, ONLY : xundef
47 !
49 !
50 USE yomhook ,ONLY : lhook, dr_hook
51 USE parkind1 ,ONLY : jprb
52 !
53 IMPLICIT NONE
54 !
55 #ifdef SFX_MPI
56 include "mpif.h"
57 #endif
58 !
59 REAL, DIMENSION(:), INTENT(IN) :: pwork
60 REAL, DIMENSION(:), INTENT(OUT) :: pwork2
61 !
62 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
63 !
64 REAL, DIMENSION(NSIZE) :: zinter
65 REAL :: xtime0
66 !
67 #ifdef SFX_MPI
68 INTEGER, DIMENSION(MPI_STATUS_SIZE) :: istatus
69 #endif
70 INTEGER :: icpt
71 INTEGER :: i,j, ip1, is1
72 INTEGER :: infompi
73 !
74 REAL(KIND=JPRB) :: zhook_handle
75 !
76 !
77 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X1D0',0,zhook_handle)
78 !
79 xwork(nindx1sfx:nindx2sfx) = xundef
80 !
81 #ifdef SFX_MPI
82 xtime0 = mpi_wtime()
83 #endif
84 !
85 IF (SIZE(pwork)>0) THEN
86  IF (present(kmask)) THEN
87  CALL unpack_same_rank(kmask,pwork,xwork(nindx1sfx:nindx2sfx))
88  ELSE
89  xwork(nindx1sfx:nindx2sfx) = pwork(:)
90  ENDIF
91 ENDIF
92 !
93 #ifdef SFX_MPI
94 xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
95 !
96 xtime0 = mpi_wtime()
97 #endif
98 !
99 !$OMP BARRIER
100 !
101 #ifdef SFX_MPI
102 xtime_omp_barr = xtime_omp_barr + (mpi_wtime() - xtime0)
103 #endif
104 !
105 IF (nrank/=npio) THEN
106  !
107 !$OMP SINGLE
108  !
109  idx_w = idx_w + 1
110  !
111 #ifdef SFX_MPI
112  xtime0 = mpi_wtime()
113  CALL mpi_send(xwork,SIZE(xwork)*kind(xwork)/4,mpi_real,npio,idx_w,ncomm,infompi)
114  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
115 #endif
116  !
117 !$OMP END SINGLE
118  !
119 ELSE
120  !
121  ip1 = SIZE(pwork2)
122  !
123 !$OMP SINGLE
124  !
125  is1 = SIZE(xwork_full)
126  !
127  IF (ip1>is1) THEN
128  DEALLOCATE(xwork_full)
129  ALLOCATE(xwork_full(ip1))
130  ENDIF
131  !
132  xwork_full(:) = 0.
133  !
134  idx_w = idx_w + 1
135  !
136  DO i=1,nproc
137  !
138 #ifdef SFX_MPI
139  xtime0 = mpi_wtime()
140 #endif
141  !
142  IF (i<nproc) THEN
143 #ifdef SFX_MPI
144  CALL mpi_recv(zinter,SIZE(zinter)*kind(zinter)/4,mpi_real,i,idx_w,ncomm,istatus,infompi)
145 #endif
146  ELSE
147  zinter(1:SIZE(xwork)) = xwork(:)
148  ENDIF
149  !
150 #ifdef SFX_MPI
151  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
152  !
153  xtime0 = mpi_wtime()
154 #endif
155  !
156  icpt = 0
157  !
158  DO j=1,SIZE(nindex)
159  !
160  IF ( nindex(j)==mod(i,nproc) ) THEN
161  icpt = icpt + 1
162  xwork_full(j) = zinter(icpt)
163  ENDIF
164  !
165  ENDDO
166  !
167 #ifdef SFX_MPI
168  xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
169 #endif
170  !
171  ENDDO
172  !
173 !$OMP END SINGLE
174  !
175  pwork2 = xwork_full(1:ip1)
176  !
177 ENDIF
178 !
179 
180 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X1D0',1,zhook_handle)
181 !
182 END SUBROUTINE gather_and_write_mpi_x1d0
183 !
184 !**************************************************************************
185 !
186 SUBROUTINE gather_and_write_mpi_x2d0(PWORK,PWORK2,KMASK)
187 !
188 USE modd_surf_par, ONLY : xundef
189 !
190 USE modd_surfex_mpi, ONLY : nindex, nproc, nrank, ncomm, npio, nsize, &
191  xtime_comm_write, xtime_omp_barr, &
192  xtime_calc_write, idx_w, wlog_mpi
193 USE modd_surfex_omp, ONLY : nindx1sfx, nindx2sfx, xwork2, xwork2_full, nblock
194 !
196 !
197 USE yomhook ,ONLY : lhook, dr_hook
198 USE parkind1 ,ONLY : jprb
199 !
200 IMPLICIT NONE
201 !
202 #ifdef SFX_MPI
203 include "mpif.h"
204 #endif
205 !
206 REAL, DIMENSION(:,:), INTENT(IN) :: pwork
207 REAL, DIMENSION(:,:), INTENT(OUT) :: pwork2
208 !
209 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
210 !
211 REAL, DIMENSION(NSIZE,SIZE(PWORK2,2)) :: zinter
212 REAL:: xtime0
213 !
214 #ifdef SFX_MPI
215 INTEGER, DIMENSION(MPI_STATUS_SIZE) :: istatus
216 #endif
217 INTEGER :: icpt, ix2, is1, is2, ip1, ip2
218 INTEGER :: i,j
219 INTEGER :: infompi
220 !
221 REAL(KIND=JPRB) :: zhook_handle
222 !
223 !
224 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X2D0',0,zhook_handle)
225 !
226 ip2 = SIZE(pwork,2)
227 ix2 = SIZE(xwork2,2)
228 !
229 !$OMP SINGLE
230 !
231 IF (ip2>ix2) THEN
232  DEALLOCATE(xwork2)
233  ALLOCATE(xwork2(nsize,ip2))
234 ENDIF
235 !
236 !$OMP END SINGLE
237 !
238 xwork2(nindx1sfx:nindx2sfx,1:ip2) = xundef
239 !
240 #ifdef SFX_MPI
241 xtime0 = mpi_wtime()
242 #endif
243 !
244 IF (SIZE(pwork,1)>0) THEN
245  IF (present(kmask)) THEN
246  CALL unpack_same_rank(kmask,pwork,xwork2(nindx1sfx:nindx2sfx,1:ip2))
247  ELSE
248  xwork2(nindx1sfx:nindx2sfx,1:ip2) = pwork(:,:)
249  ENDIF
250 ENDIF
251 !
252 #ifdef SFX_MPI
253 xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
254 !
255 xtime0 = mpi_wtime()
256 #endif
257 !
258 !$OMP BARRIER
259 !
260 #ifdef SFX_MPI
261 xtime_omp_barr = xtime_omp_barr + (mpi_wtime() - xtime0)
262 #endif
263 !
264 IF (nrank/=npio) THEN
265  !
266 !$OMP SINGLE
267  !
268  idx_w = idx_w + 1
269  !
270 #ifdef SFX_MPI
271  xtime0 = mpi_wtime()
272  CALL mpi_send(xwork2(:,1:ip2),nsize*ip2*kind(xwork2)/4,mpi_real,npio,idx_w,ncomm,infompi)
273  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
274 #endif
275  !
276 !$OMP END SINGLE
277  !
278 ELSE
279  !
280  ip1 = SIZE(pwork2,1)
281  !
282 !$OMP SINGLE
283  !
284  is1 = SIZE(xwork2_full,1)
285  is2 = SIZE(xwork2_full,2)
286  !
287  IF (ip1>is1 .OR. ip2>is2) THEN
288  DEALLOCATE(xwork2_full)
289  ALLOCATE(xwork2_full(max(ip1,is1),max(ip2,is2)))
290  ENDIF
291  !
292  xwork2_full(1:ip1,1:ip2) = 0.
293  !
294  idx_w = idx_w + 1
295  !
296  DO i=1,nproc
297  !
298 #ifdef SFX_MPI
299  xtime0 = mpi_wtime()
300 #endif
301  !
302  IF (i<nproc) THEN
303 #ifdef SFX_MPI
304  CALL mpi_recv(zinter,SIZE(zinter)*kind(zinter)/4,mpi_real,i,idx_w,ncomm,istatus,infompi)
305 #endif
306  ELSE
307  zinter(:,:) = xwork2(:,1:ip2)
308  ENDIF
309 ! !
310 #ifdef SFX_MPI
311  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
312  !
313  xtime0 = mpi_wtime()
314 #endif
315  !
316  icpt = 0
317  !
318  DO j=1,SIZE(nindex)
319  !
320  IF ( nindex(j)==mod(i,nproc) ) THEN
321  icpt = icpt + 1
322  xwork2_full(j,1:ip2) = zinter(icpt,:)
323  ENDIF
324  !
325  ENDDO
326  !
327 #ifdef SFX_MPI
328  xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
329 #endif
330  !
331  ENDDO
332  !
333 !$OMP END SINGLE
334  !
335  pwork2(:,:) = xwork2_full(1:ip1,1:ip2)
336  !
337 ENDIF
338 !
339 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X2D0',1,zhook_handle)
340 !
341 !
342 END SUBROUTINE gather_and_write_mpi_x2d0
343 !
344 !**************************************************************************
subroutine gather_and_write_mpi_x2d0(PWORK, PWORK2, KMASK)
subroutine wlog_mpi(HLOG, PLOG, KLOG, KLOG2, OLOG)
subroutine gather_and_write_mpi_x1d0(PWORK, PWORK2, KMASK)