SURFEX  V8_0
Surfex V8_0 release
 All Classes Files Functions Variables
gather_and_write_mpi.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_n1d(KWORK,KWORK2,KMASK)
16 !
17 INTEGER, DIMENSION(:), INTENT(IN) :: kwork
18 INTEGER, DIMENSION(:), INTENT(OUT) :: kwork2
19 !
20 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
21 !
22 END SUBROUTINE gather_and_write_mpi_n1d
23 !
24 SUBROUTINE gather_and_write_mpi_n2d(KWORK,KWORK2,KMASK)
25 !
26 INTEGER, DIMENSION(:,:), INTENT(IN) :: kwork
27 INTEGER, DIMENSION(:,:), INTENT(OUT) :: kwork2
28 !
29 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
30 !
31 END SUBROUTINE gather_and_write_mpi_n2d
32 !
33 SUBROUTINE gather_and_write_mpi_x1d(PWORK,PWORK2,KMASK)
34 !
35 REAL, DIMENSION(:), INTENT(IN) :: pwork
36 REAL(KIND=8), DIMENSION(:), INTENT(OUT) :: pwork2
37 !
38 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
39 !
40 END SUBROUTINE gather_and_write_mpi_x1d
41 !
42 SUBROUTINE gather_and_write_mpi_x2d(PWORK,PWORK2,KMASK)
43 !
44 REAL, DIMENSION(:,:), INTENT(IN) :: pwork
45 REAL(KIND=8), DIMENSION(:,:), INTENT(OUT) :: pwork2
46 !
47 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
48 !
49 END SUBROUTINE gather_and_write_mpi_x2d
50 !
51 SUBROUTINE gather_and_write_mpi_x1dk4(PWORK,PWORK2,KMASK)
52 !
53 REAL, DIMENSION(:), INTENT(IN) :: pwork
54 REAL(KIND=4), DIMENSION(:), INTENT(OUT) :: pwork2
55 !
56 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
57 !
58 END SUBROUTINE gather_and_write_mpi_x1dk4
59 !
60 SUBROUTINE gather_and_write_mpi_x2dk4(PWORK,PWORK2,KMASK)
61 !
62 REAL, DIMENSION(:,:), INTENT(IN) :: pwork
63 REAL(KIND=4), DIMENSION(:,:), INTENT(OUT) :: pwork2
64 !
65 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
66 !
67 END SUBROUTINE gather_and_write_mpi_x2dk4
68 !
69 END INTERFACE
70 !
72 !
73 SUBROUTINE gather_and_write_mpi_n1d(KWORK,KWORK2,KMASK)
74 !
75 USE modd_surfex_mpi, ONLY : nindex, nproc, nrank, ncomm, npio, nsize, &
76  xtime_calc_write, xtime_comm_write, &
77  xtime_omp_barr, idx_w, wlog_mpi
78 USE modd_surfex_omp, ONLY : nindx1sfx, nindx2sfx, nwork, nwork_full
79 !
81 !
82 USE yomhook ,ONLY : lhook, dr_hook
83 USE parkind1 ,ONLY : jprb
84 !
85 IMPLICIT NONE
86 !
87 #ifdef SFX_MPI
88 include "mpif.h"
89 #endif
90 !
91 INTEGER, DIMENSION(:), INTENT(IN) :: kwork
92 INTEGER, DIMENSION(:), INTENT(OUT) :: kwork2
93 !
94 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
95 !
96 INTEGER, DIMENSION(NSIZE) :: iinter
97 REAL :: xtime0
98 !
99 #ifdef SFX_MPI
100 INTEGER, DIMENSION(MPI_STATUS_SIZE) :: istatus
101 #endif
102 INTEGER :: icpt
103 INTEGER :: i,j, ip1, is1
104 INTEGER :: infompi
105 !
106 REAL(KIND=JPRB) :: zhook_handle
107 !
108 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_N1D',0,zhook_handle)
109 !
110 !$OMP BARRIER
111 !
112 nwork(nindx1sfx:nindx2sfx) = 0
113 !
114 #ifdef SFX_MPI
115 xtime0 = mpi_wtime()
116 #endif
117 !
118 IF (present(kmask)) THEN
119  CALL unpack_same_rank(kmask,kwork,nwork(nindx1sfx:nindx2sfx))
120 ELSE
121  nwork(nindx1sfx:nindx2sfx) = kwork(:)
122 ENDIF
123 !
124 #ifdef SFX_MPI
125 xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
126 !
127 xtime0 = mpi_wtime()
128 #endif
129 !
130 !$OMP BARRIER
131 !
132 #ifdef SFX_MPI
133 xtime_omp_barr = xtime_omp_barr + (mpi_wtime() - xtime0)
134 #endif
135 !
136 IF (nrank/=npio) THEN
137  !
138 !$OMP SINGLE
139  !
140  idx_w = idx_w + 1
141  !
142 #ifdef SFX_MPI
143  xtime0 = mpi_wtime()
144  CALL mpi_send(nwork,SIZE(nwork)*kind(nwork)/4,mpi_integer,npio,idx_w,ncomm,infompi)
145  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
146 #endif
147  !
148 !$OMP END SINGLE
149  !
150 ELSE
151  !
152  ip1 = SIZE(kwork2)
153  !
154 !$OMP SINGLE
155  !
156  is1 = SIZE(nwork_full)
157  !
158  IF (ip1>is1) THEN
159  DEALLOCATE(nwork_full)
160  ALLOCATE(nwork_full(ip1))
161  ENDIF
162  !
163  nwork_full(:) = 0
164  !
165  idx_w = idx_w + 1
166  !
167  DO i=1,nproc
168  !
169 #ifdef SFX_MPI
170  xtime0 = mpi_wtime()
171 #endif
172  !
173  IF (i<nproc) THEN
174 #ifdef SFX_MPI
175  CALL mpi_recv(iinter,SIZE(iinter)*kind(iinter)/4,mpi_integer,i,idx_w,ncomm,istatus,infompi)
176 #endif
177  ELSE
178  iinter(1:SIZE(nwork)) = nwork(:)
179  ENDIF
180  !
181 #ifdef SFX_MPI
182  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
183  !
184  xtime0 = mpi_wtime()
185 #endif
186  !
187  icpt = 0
188  !
189  DO j=1,SIZE(nindex)
190  !
191  IF ( nindex(j)==mod(i,nproc) ) THEN
192  icpt = icpt + 1
193  nwork_full(j) = iinter(icpt)
194  ENDIF
195  !
196  ENDDO
197  !
198 #ifdef SFX_MPI
199  xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
200 #endif
201  !
202  ENDDO
203  !
204 !$OMP END SINGLE
205  !
206  kwork2(:) = nwork_full(1:ip1)
207  !
208 ENDIF
209 !
210 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_N1D',1,zhook_handle)
211 !
212 !
213 END SUBROUTINE gather_and_write_mpi_n1d
214 !
215 !**************************************************************************
216 !
217 SUBROUTINE gather_and_write_mpi_n2d(KWORK,KWORK2,KMASK)
218 !
219 USE modd_surfex_mpi, ONLY : nindex, nproc, nrank, ncomm, npio, nsize, &
220  xtime_calc_write, xtime_comm_write, &
221  xtime_omp_barr, idx_w, wlog_mpi
222 USE modd_surfex_omp, ONLY : nindx1sfx, nindx2sfx, nwork2, nwork2_full
223 !
225 !
226 USE yomhook ,ONLY : lhook, dr_hook
227 USE parkind1 ,ONLY : jprb
228 !
229 IMPLICIT NONE
230 !
231 #ifdef SFX_MPI
232 include "mpif.h"
233 #endif
234 !
235 INTEGER, DIMENSION(:,:), INTENT(IN) :: kwork
236 INTEGER, DIMENSION(:,:), INTENT(OUT) :: kwork2
237 !
238 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
239 !
240 INTEGER, DIMENSION(NSIZE,SIZE(KWORK2,2)) :: iinter
241 REAL :: xtime0
242 !
243 #ifdef SFX_MPI
244 INTEGER, DIMENSION(MPI_STATUS_SIZE) :: istatus
245 #endif
246 INTEGER :: icpt, ix2, is1, is2, ip1, ip2
247 INTEGER :: i,j
248 INTEGER :: infompi
249 !
250 REAL(KIND=JPRB) :: zhook_handle
251 !
252 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_N2D',0,zhook_handle)
253 !
254 ip2 = SIZE(kwork,2)
255 ix2 = SIZE(nwork2,2)
256 !
257 !$OMP SINGLE
258 !
259 IF (ip2>ix2) THEN
260  DEALLOCATE(nwork2)
261  ALLOCATE(nwork2(nsize,ip2))
262 ENDIF
263 !
264 !$OMP END SINGLE
265 !
266 nwork2(nindx1sfx:nindx2sfx,1:ip2) = 0
267 !
268 #ifdef SFX_MPI
269 xtime0 = mpi_wtime()
270 #endif
271 !
272 IF (SIZE(kwork,1)>0) THEN
273  IF (present(kmask)) THEN
274  CALL unpack_same_rank(kmask,kwork,nwork2(nindx1sfx:nindx2sfx,1:ip2))
275  ELSE
276  nwork2(nindx1sfx:nindx2sfx,1:ip2) = kwork(:,:)
277  ENDIF
278 ENDIF
279 !
280 #ifdef SFX_MPI
281 xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
282 !
283 xtime0 = mpi_wtime()
284 #endif
285 !
286 !$OMP BARRIER
287 !
288 #ifdef SFX_MPI
289 xtime_omp_barr = xtime_omp_barr + (mpi_wtime() - xtime0)
290 #endif
291 !
292 IF (nrank/=npio) THEN
293  !
294 !$OMP SINGLE
295  !
296  idx_w = idx_w + 1
297  !
298 #ifdef SFX_MPI
299  xtime0 = mpi_wtime()
300  CALL mpi_send(nwork2(:,1:ip2),nsize*ip2*kind(nwork2)/4,mpi_integer,npio,idx_w,ncomm,infompi)
301  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
302 #endif
303  !
304 !$OMP END SINGLE
305  !
306 ELSE
307  !
308  ip1 = SIZE(kwork2,1)
309  !
310 !$OMP SINGLE
311  !
312  is1 = SIZE(nwork2_full,1)
313  is2 = SIZE(nwork2_full,2)
314  !
315  IF (ip1>is1 .OR. ip2>is2) THEN
316  DEALLOCATE(nwork2_full)
317  ALLOCATE(nwork2_full(max(ip1,is1),max(ip2,is2)))
318  ENDIF
319  !
320  nwork2_full(:,:) = 0
321  !
322  idx_w = idx_w + 1
323  !
324  DO i=1,nproc
325  !
326 #ifdef SFX_MPI
327  xtime0 = mpi_wtime()
328 #endif
329  !
330  IF (i<nproc) THEN
331 #ifdef SFX_MPI
332  CALL mpi_recv(iinter,SIZE(iinter)*kind(iinter)/4,mpi_integer,i,idx_w,ncomm,istatus,infompi)
333 #endif
334  ELSE
335  iinter(:,:) = nwork2(:,1:ip2)
336  ENDIF
337  !
338 #ifdef SFX_MPI
339  xtime_comm_write = xtime_comm_write + (mpi_wtime() - xtime0)
340  !
341  xtime0 = mpi_wtime()
342 #endif
343  !
344  icpt = 0
345  !
346  DO j=1,SIZE(nindex)
347  !
348  IF ( nindex(j)==mod(i,nproc) ) THEN
349  icpt = icpt + 1
350  nwork2_full(j,1:ip2) = iinter(icpt,:)
351  ENDIF
352  !
353  ENDDO
354  !
355 #ifdef SFX_MPI
356  xtime_calc_write = xtime_calc_write + (mpi_wtime() - xtime0)
357 #endif
358  !
359  ENDDO
360  !
361 !$OMP END SINGLE
362  !
363  kwork2(:,:) = nwork2_full(1:ip1,1:ip2)
364  !
365 ENDIF
366 !
367 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_N2D',1,zhook_handle)
368 !
369 !
370 END SUBROUTINE gather_and_write_mpi_n2d
371 !
372 !**************************************************************************
373 !
374 SUBROUTINE gather_and_write_mpi_x1d(PWORK,PWORK2,KMASK)
375 !
377 !
378 USE modd_surfex_mpi, ONLY : nrank, npio
379 !
380 USE yomhook ,ONLY : lhook, dr_hook
381 USE parkind1 ,ONLY : jprb
382 !
383 IMPLICIT NONE
384 !
385 REAL, DIMENSION(:), INTENT(IN) :: pwork
386 REAL(KIND=8), DIMENSION(:), INTENT(OUT) :: pwork2
387 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
388 !
389 REAL, DIMENSION(SIZE(PWORK2)) :: zinter
390 REAL(KIND=JPRB) :: zhook_handle
391 !
392 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X1D',0,zhook_handle)
393 !
394 IF (present(kmask)) THEN
395  CALL gather_and_write_mpi_k4(pwork,zinter,kmask)
396 ELSE
397  CALL gather_and_write_mpi_k4(pwork,zinter)
398 ENDIF
399 !
400 IF (nrank==npio) THEN
401  pwork2(:) = zinter(:)
402 ENDIF
403 !
404 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X1D',1,zhook_handle)
405 !
406 END SUBROUTINE gather_and_write_mpi_x1d
407 !
408 !**************************************************************************
409 !
410 SUBROUTINE gather_and_write_mpi_x2d(PWORK,PWORK2,KMASK)
411 !
413 !
414 USE modd_surfex_mpi, ONLY : nrank, npio
415 !
416 USE yomhook ,ONLY : lhook, dr_hook
417 USE parkind1 ,ONLY : jprb
418 !
419 IMPLICIT NONE
420 !
421 REAL, DIMENSION(:,:), INTENT(IN) :: pwork
422 REAL(KIND=8), DIMENSION(:,:), INTENT(OUT) :: pwork2
423 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
424 !
425 REAL, DIMENSION(SIZE(PWORK2,1),SIZE(PWORK2,2)) :: zinter
426 REAL(KIND=JPRB) :: zhook_handle
427 !
428 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X2D',0,zhook_handle)
429 !
430 IF (present(kmask)) THEN
431  CALL gather_and_write_mpi_k4(pwork,zinter,kmask)
432 ELSE
433  CALL gather_and_write_mpi_k4(pwork,zinter)
434 ENDIF
435 !
436 IF (nrank==npio) THEN
437  pwork2(:,:) = zinter(:,:)
438 ENDIF
439 !
440 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X2D',1,zhook_handle)
441 !
442 END SUBROUTINE gather_and_write_mpi_x2d
443 !
444 !**************************************************************************
445 !
446 SUBROUTINE gather_and_write_mpi_x1dk4(PWORK,PWORK2,KMASK)
447 !
449 !
450 USE modd_surfex_mpi, ONLY : nrank, npio
451 !
452 USE yomhook ,ONLY : lhook, dr_hook
453 USE parkind1 ,ONLY : jprb
454 !
455 IMPLICIT NONE
456 !
457 REAL, DIMENSION(:), INTENT(IN) :: pwork
458 REAL(KIND=4), DIMENSION(:), INTENT(OUT) :: pwork2
459 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
460 !
461 REAL, DIMENSION(SIZE(PWORK2)) :: zinter
462 REAL(KIND=JPRB) :: zhook_handle
463 !
464 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X1DK4',0,zhook_handle)
465 !
466 IF (present(kmask)) THEN
467  CALL gather_and_write_mpi_k4(pwork,zinter,kmask)
468 ELSE
469  CALL gather_and_write_mpi_k4(pwork,zinter)
470 ENDIF
471 !
472 IF (nrank==npio) THEN
473  pwork2(:) = zinter(:)
474 ENDIF
475 !
476 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X1DK4',1,zhook_handle)
477 !
478 END SUBROUTINE gather_and_write_mpi_x1dk4
479 !
480 !**************************************************************************
481 !
482 SUBROUTINE gather_and_write_mpi_x2dk4(PWORK,PWORK2,KMASK)
483 !
485 !
486 USE modd_surfex_mpi, ONLY : nrank, npio
487 !
488 USE yomhook ,ONLY : lhook, dr_hook
489 USE parkind1 ,ONLY : jprb
490 !
491 IMPLICIT NONE
492 !
493 REAL, DIMENSION(:,:), INTENT(IN) :: pwork
494 REAL(KIND=4), DIMENSION(:,:), INTENT(OUT) :: pwork2
495 INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL :: kmask
496 !
497 REAL, DIMENSION(SIZE(PWORK2,1),SIZE(PWORK2,2)) :: zinter
498 REAL(KIND=JPRB) :: zhook_handle
499 !
500 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X2DK4',0,zhook_handle)
501 !
502 IF (present(kmask)) THEN
503  CALL gather_and_write_mpi_k4(pwork,zinter,kmask)
504 ELSE
505  CALL gather_and_write_mpi_k4(pwork,zinter)
506 ENDIF
507 !
508 IF (nrank==npio) THEN
509  pwork2(:,:) = zinter(:,:)
510 ENDIF
511 !
512 IF (lhook) CALL dr_hook('GATHER_AND_WRITE_MPI_X2DK4',1,zhook_handle)
513 !
514 END SUBROUTINE gather_and_write_mpi_x2dk4
515 
subroutine gather_and_write_mpi_x2d(PWORK, PWORK2, KMASK)
subroutine gather_and_write_mpi_n1d(KWORK, KWORK2, KMASK)
subroutine gather_and_write_mpi_n2d(KWORK, KWORK2, KMASK)
subroutine gather_and_write_mpi_x1dk4(PWORK, PWORK2, KMASK)
subroutine wlog_mpi(HLOG, PLOG, KLOG, KLOG2, OLOG)
subroutine gather_and_write_mpi_x2dk4(PWORK, PWORK2, KMASK)
subroutine gather_and_write_mpi_x1d(PWORK, PWORK2, KMASK)