SURFEX v8.1
General documentation of Surfex
mpl_allgatherv_mod.F90
Go to the documentation of this file.
1 #ifdef RS6K
2 @process nocheck
3 #endif
5 
6 !**** MPL_ALLGATHERV Send data to all processes
7 
8 ! Purpose.
9 ! --------
10 ! Send a message to all processes from a buffer.
11 ! The data may be REAL*4, REAL*8,or INTEGER, one dimensional array
12 ! REAL*4,or REAL*8, two dimensional array
13 ! or INTEGER scalar
14 
15 !** Interface.
16 ! ----------
17 ! CALL MPL_ALLGATHERV
18 
19 ! Input required arguments :
20 ! -------------------------
21 ! PSENDBUF - buffer containing message
22 ! (can be type REAL*4, REAL*8 or INTEGER)
23 ! PRECVBUF - buffer containing message
24 ! (can be type REAL*4, REAL*8 or INTEGER)
25 ! KRECVCOUNTS-number of elements received from each process
26 
27 ! Input optional arguments :
28 ! -------------------------
29 ! KCOMM - Communicator number if different from MPI_COMM_WORLD
30 ! or from that established as the default
31 ! by an MPL communicator routine
32 ! KMP_TYPE - buffering type (see MPL_BUFFER_METHOD)
33 ! overrides value provided to MPL_BUFFER_METHOD
34 ! KRECVDISPL -displacements in PRECVBUF at which to place
35 ! the incoming data
36 ! CDSTRING - Character string for ABORT messages
37 ! used when KERROR is not provided
38 
39 ! Output required arguments :
40 ! -------------------------
41 ! none
42 
43 ! Output optional arguments :
44 ! -------------------------
45 ! KREQUEST - Communication request
46 ! required when buffering type is non-blocking
47 ! KERROR - return error code. If not supplied,
48 ! MPL_ALLGATHERV aborts when an error is detected.
49 ! Author.
50 ! -------
51 ! D.Dent, M.Hamrud ECMWF
52 
53 ! Modifications.
54 ! --------------
55 ! Original: 2000-11-23
56 ! Threadsafe: 2004-12-15 J.Hague
57 ! M.Hamrud : 2014-10-22 : Add nonblocking option
58 ! F. Vana 05-Mar-2015 Support for single precision
59 
60 ! ------------------------------------------------------------------
61 
62 USE parkind1 ,ONLY : jprd, jpim ,jprm
63 
64 USE mpl_mpif
66 USE mpl_stats_mod
67 USE yommplstats
69 USE mpl_send_mod
70 USE mpl_recv_mod
72 
73 IMPLICIT NONE
74 
75 PRIVATE
76 
77 LOGICAL :: llabort=.true.
78 LOGICAL :: llbarrier
79 
80 INTERFACE mpl_allgatherv
83 END INTERFACE
84 
85 PUBLIC mpl_allgatherv
86 
87 CONTAINS
88 
89 
90 SUBROUTINE mpl_allgatherv_real4(PSENDBUF,PRECVBUF,KRECVCOUNTS,KRECVDISPL, &
91  & KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
92 
93 
94 #ifdef USE_8_BYTE_WORDS
95  USE mpi4to8, ONLY : &
96  mpi_comm_size => mpi_comm_size8, mpi_allgatherv => mpi_allgatherv8
97 #endif
98 
99 
100 
101 REAL(KIND=JPRM) :: PSENDBUF(:)
102 REAL(KIND=JPRM) :: PRECVBUF(:)
103 INTEGER(KIND=JPIM),INTENT(IN) :: KRECVCOUNTS(:)
104 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM,KMP_TYPE
105 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KREQUEST
106 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
107 
108 INTEGER(KIND=JPIM) :: IR,ISENDCOUNT,IRECVCOUNT
109 INTEGER(KIND=JPIM) :: IMP_TYPE
110 INTEGER(KIND=JPIM) :: ICOMM,IERROR,IPL_NUMPROC
111 INTEGER(KIND=JPIM) :: ITID
112 INTEGER(KIND=JPIM),ALLOCATABLE :: IRECVDISPL(:)
113 
114 itid = oml_my_thread()
115 isendcount = SIZE(psendbuf)
116 isendcount = max(0,isendcount) ! Bug? on IBM
117 irecvcount = SIZE(precvbuf)
118 
119 !--------- Preamble repeated for threadsafe--------------
120 IF(PRESENT(kcomm)) THEN
121  icomm=kcomm
122 ELSE
123  icomm=mpl_comm_oml(itid)
124 ENDIF
125 
126 IF(icomm == mpl_comm_oml(itid)) THEN
127  ipl_numproc = mpl_numproc
128 ELSE
129  CALL mpi_comm_size(icomm,ipl_numproc,ierror)
130 ENDIF
131 
132 ALLOCATE(irecvdispl(ipl_numproc))
133 IF(PRESENT(krecvdispl)) THEN
134  irecvdispl(:) = krecvdispl(:)
135 ELSE
136  irecvdispl(:) = 0
137  DO ir=2, ipl_numproc
138  irecvdispl(ir) = irecvdispl(ir-1) + krecvcounts(ir-1)
139  ENDDO
140 ENDIF
141 IF(PRESENT(kmp_type)) THEN
142  imp_type=kmp_type
143 ELSE
144  imp_type=mpl_method
145 ENDIF
146 IF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
147  IF(.NOT.PRESENT(krequest)) CALL mpl_message(cdmessage='MPL_ALLGATHERV: KREQUEST MISSING',ldabort=llabort)
148 ENDIF
149 !--------- End of Preamble --------------
150 
151 
152 IF(imp_type == jp_blocking_standard .OR. imp_type == jp_blocking_buffered) THEN
153  CALL mpi_allgatherv(psendbuf(1),isendcount,int(mpi_real4),precvbuf(1),&
154  & krecvcounts,irecvdispl,int(mpi_real4),icomm,ierror)
155 ELSEIF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
156  CALL mpi_iallgatherv(psendbuf(1),isendcount,int(mpi_real4),precvbuf(1),&
157  & krecvcounts,irecvdispl,int(mpi_real4),icomm,krequest,ierror)
158 ENDIF
159 IF(lmplstats) THEN
160  CALL mpl_sendstats(isendcount,int(mpi_real4))
161  CALL mpl_recvstats(sum(krecvcounts),int(mpi_real4))
162 ENDIF
163 
164 IF(mpl_output > 1 )THEN
165  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLGATHERV ',isendcount,irecvcount,icomm
166 ENDIF
167 IF(PRESENT(kerror)) THEN
168  kerror=ierror
169 ELSE
170  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLGATHERV',&
171  & cdstring,ldabort=llabort)
172 ENDIF
173 DEALLOCATE(irecvdispl)
174 
175 END SUBROUTINE mpl_allgatherv_real4
176 
177 SUBROUTINE mpl_allgatherv_real8(PSENDBUF,PRECVBUF,KRECVCOUNTS,KRECVDISPL, &
178  & KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
180 
181 #ifdef USE_8_BYTE_WORDS
182  USE mpi4to8, ONLY : &
183  mpi_comm_size => mpi_comm_size8, mpi_allgatherv => mpi_allgatherv8
184 #endif
185 
186 
187 
188 REAL(KIND=JPRD) :: PSENDBUF(:)
189 REAL(KIND=JPRD) :: PRECVBUF(:)
190 INTEGER(KIND=JPIM),INTENT(IN) :: KRECVCOUNTS(:)
191 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM,KMP_TYPE
192 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KREQUEST
193 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
194 
195 INTEGER(KIND=JPIM) :: IR,ISENDCOUNT,IRECVCOUNT
196 INTEGER(KIND=JPIM) :: IMP_TYPE
197 INTEGER(KIND=JPIM) :: ICOMM,IERROR,IPL_NUMPROC
198 INTEGER(KIND=JPIM) :: ITID,J
199 INTEGER(KIND=JPIM),ALLOCATABLE :: IRECVDISPL(:)
200 itid = oml_my_thread()
201 isendcount = SIZE(psendbuf)
202 isendcount = max(0,isendcount) ! Bug? on IBM
203 irecvcount = SIZE(precvbuf)
204 
205 !--------- Preamble repeated for threadsafe--------------
206 IF(PRESENT(kcomm)) THEN
207  icomm=kcomm
208 ELSE
209  icomm=mpl_comm_oml(itid)
210 ENDIF
211 
212 IF(icomm == mpl_comm_oml(itid)) THEN
213  ipl_numproc = mpl_numproc
214 ELSE
215  CALL mpi_comm_size(icomm,ipl_numproc,ierror)
216 ENDIF
217 
218 ALLOCATE(irecvdispl(ipl_numproc))
219 IF(PRESENT(krecvdispl)) THEN
220  DO j=1,min(SIZE(irecvdispl),SIZE(krecvdispl))
221  irecvdispl(j) = krecvdispl(j)
222  ENDDO
223 ELSE
224  irecvdispl(:) = 0
225  DO ir=2, ipl_numproc
226  irecvdispl(ir) = irecvdispl(ir-1) + krecvcounts(ir-1)
227  ENDDO
228 ENDIF
229 IF(PRESENT(kmp_type)) THEN
230  imp_type=kmp_type
231 ELSE
232  imp_type=mpl_method
233 ENDIF
234 IF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
235  IF(.NOT.PRESENT(krequest)) CALL mpl_message(cdmessage='MPL_ALLGATHERV: KREQUEST MISSING',ldabort=llabort)
236 ENDIF
237 !!--------- End of Preamble --------------
238 
239 ierror=0
240 
241 IF(imp_type == jp_blocking_standard .OR. imp_type == jp_blocking_buffered) THEN
242  CALL mpi_allgatherv(psendbuf(1),isendcount,int(mpi_real8),precvbuf(1),&
243  & krecvcounts,irecvdispl,int(mpi_real8),icomm,ierror)
244 ELSEIF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
245  CALL mpi_iallgatherv(psendbuf(1),isendcount,int(mpi_real8),precvbuf(1),&
246  & krecvcounts,irecvdispl,int(mpi_real8),icomm,krequest,ierror)
247 ENDIF
248 
249 IF(lmplstats) THEN
250  CALL mpl_sendstats(isendcount,int(mpi_real8))
251  CALL mpl_recvstats(sum(krecvcounts),int(mpi_real8))
252 ENDIF
253 
254 IF(mpl_output > 1 )THEN
255  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLGATHERV ',isendcount,irecvcount,icomm
256 ENDIF
257 IF(PRESENT(kerror)) THEN
258  kerror=ierror
259 ELSE
260  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLGATHERV',cdstring,&
261  & ldabort=llabort)
262 ENDIF
263 DEALLOCATE(irecvdispl)
264 
265 END SUBROUTINE mpl_allgatherv_real8
266 
267 SUBROUTINE mpl_allgatherv_int(KSENDBUF,KRECVBUF,KRECVCOUNTS,KRECVDISPL, &
268  & KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
270 
271 #ifdef USE_8_BYTE_WORDS
272  USE mpi4to8, ONLY : &
273  mpi_comm_size => mpi_comm_size8, mpi_allgatherv => mpi_allgatherv8
274 #endif
275 
276 
277 
278 INTEGER(KIND=JPIM) :: KSENDBUF(:)
279 INTEGER(KIND=JPIM) :: KRECVBUF(:)
280 INTEGER(KIND=JPIM),INTENT(IN) :: KRECVCOUNTS(:)
281 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM,KMP_TYPE
282 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KREQUEST
283 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
284 
285 INTEGER(KIND=JPIM) :: IR,ISENDCOUNT,IRECVCOUNT
286 INTEGER(KIND=JPIM) :: IMP_TYPE
287 INTEGER(KIND=JPIM) :: ICOMM,IERROR,IPL_NUMPROC
288 INTEGER(KIND=JPIM) :: ITID
289 INTEGER(KIND=JPIM),ALLOCATABLE :: IRECVDISPL(:)
290 itid = oml_my_thread()
291 isendcount = SIZE(ksendbuf)
292 isendcount = max(0,isendcount) ! Bug? on IBM
293 irecvcount = SIZE(krecvbuf)
294 
295 !--------- Preamble repeated for threadsafe--------------
296 IF(PRESENT(kcomm)) THEN
297  icomm=kcomm
298 ELSE
299  icomm=mpl_comm_oml(itid)
300 ENDIF
301 
302 IF(icomm == mpl_comm_oml(itid)) THEN
303  ipl_numproc = mpl_numproc
304 ELSE
305  CALL mpi_comm_size(icomm,ipl_numproc,ierror)
306 ENDIF
307 
308 ALLOCATE(irecvdispl(ipl_numproc))
309 IF(PRESENT(krecvdispl)) THEN
310  irecvdispl(:) = krecvdispl(:)
311 ELSE
312  irecvdispl(:) = 0
313  DO ir=2, ipl_numproc
314  irecvdispl(ir) = irecvdispl(ir-1) + krecvcounts(ir-1)
315  ENDDO
316 ENDIF
317 IF(PRESENT(kmp_type)) THEN
318  imp_type=kmp_type
319 ELSE
320  imp_type=mpl_method
321 ENDIF
322 IF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
323  IF(.NOT.PRESENT(krequest)) CALL mpl_message(cdmessage='MPL_ALLGATHERV: KREQUEST MISSING',ldabort=llabort)
324 ENDIF
325 !--------- End of Preamble --------------
326 
327 ierror=0
328 IF(imp_type == jp_blocking_standard .OR. imp_type == jp_blocking_buffered) THEN
329  CALL mpi_allgatherv(ksendbuf(1),isendcount,int(mpi_integer),krecvbuf(1),&
330  & krecvcounts,irecvdispl,int(mpi_integer),icomm,ierror)
331 ELSEIF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
332  CALL mpi_iallgatherv(ksendbuf(1),isendcount,int(mpi_integer),krecvbuf(1),&
333  & krecvcounts,irecvdispl,int(mpi_integer),icomm,krequest,ierror)
334 ENDIF
335 
336 IF(lmplstats) THEN
337  CALL mpl_sendstats(isendcount,int(mpi_integer))
338  CALL mpl_recvstats(sum(krecvcounts),int(mpi_integer))
339 ENDIF
340 
341 IF(mpl_output > 1 )THEN
342  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLGATHERV ',isendcount,irecvcount,icomm
343 ENDIF
344 IF(PRESENT(kerror)) THEN
345  kerror=ierror
346 ELSE
347  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLGATHERV',cdstring,ldabort=llabort)
348 ENDIF
349 DEALLOCATE(irecvdispl)
350 
351 END SUBROUTINE mpl_allgatherv_int
352 
353 SUBROUTINE mpl_allgatherv_int_scalar(KSENDBUF,KRECVBUF,KRECVCOUNTS,KRECVDISPL, &
354  & KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
356 
357 #ifdef USE_8_BYTE_WORDS
358  USE mpi4to8, ONLY : &
359  mpi_comm_size => mpi_comm_size8, mpi_allgatherv => mpi_allgatherv8
360 #endif
361 
362 
363 
364 INTEGER(KIND=JPIM) :: KSENDBUF
365 INTEGER(KIND=JPIM) :: KRECVBUF(:)
366 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVCOUNTS(:) ! Not used; for compatibility only
367 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KRECVDISPL(:),KCOMM,KMP_TYPE
368 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KREQUEST
369 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
370 
371 INTEGER(KIND=JPIM) :: IR,ISENDCOUNT,IRECVCOUNT
372 INTEGER(KIND=JPIM) :: IMP_TYPE
373 INTEGER(KIND=JPIM) :: IRECVCOUNTS(mpl_numproc)
374 INTEGER(KIND=JPIM) :: ICOMM,IERROR,IPL_NUMPROC
375 INTEGER(KIND=JPIM) :: ITID
376 INTEGER(KIND=JPIM),ALLOCATABLE :: IRECVDISPL(:)
377 itid = oml_my_thread()
378 isendcount = 1
379 irecvcount = SIZE(krecvbuf)
380 
381 irecvcounts(:) = 1
382 !--------- Preamble repeated for threadsafe--------------
383 IF(PRESENT(kcomm)) THEN
384  icomm=kcomm
385 ELSE
386  icomm=mpl_comm_oml(itid)
387 ENDIF
388 
389 IF(icomm == mpl_comm_oml(itid)) THEN
390  ipl_numproc = mpl_numproc
391 ELSE
392  CALL mpi_comm_size(icomm,ipl_numproc,ierror)
393 ENDIF
394 
395 ALLOCATE(irecvdispl(ipl_numproc))
396 IF(PRESENT(krecvdispl)) THEN
397  irecvdispl(:) = krecvdispl(:)
398 ELSE
399  irecvdispl(:) = 0
400  DO ir=2, ipl_numproc
401  irecvdispl(ir) = irecvdispl(ir-1) + irecvcounts(ir-1)
402  ENDDO
403 ENDIF
404 IF(PRESENT(kmp_type)) THEN
405  imp_type=kmp_type
406 ELSE
407  imp_type=mpl_method
408 ENDIF
409 IF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
410  IF(.NOT.PRESENT(krequest)) CALL mpl_message(cdmessage='MPL_ALLGATHERV: KREQUEST MISSING',ldabort=llabort)
411 ENDIF
412 !--------- End of Preamble --------------
413 
414 IF(imp_type == jp_blocking_standard .OR. imp_type == jp_blocking_buffered) THEN
415  CALL mpi_allgatherv(ksendbuf,isendcount,int(mpi_integer),krecvbuf(1),irecvcounts,&
416  & irecvdispl,int(mpi_integer),icomm,ierror)
417 ELSEIF(imp_type == jp_non_blocking_standard .OR. imp_type == jp_non_blocking_buffered) THEN
418  CALL mpi_iallgatherv(ksendbuf,isendcount,int(mpi_integer),krecvbuf(1),irecvcounts,&
419  & irecvdispl,int(mpi_integer),icomm,krequest,ierror)
420 ENDIF
421 IF(lmplstats) THEN
422  CALL mpl_sendstats(isendcount,int(mpi_integer))
423  CALL mpl_recvstats(sum(irecvcounts),int(mpi_integer))
424 ENDIF
425 
426 IF(mpl_output > 1 )THEN
427  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLGATHERV ',isendcount,irecvcount,icomm
428 ENDIF
429 IF(PRESENT(kerror)) THEN
430  kerror=ierror
431 ELSE
432  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLGATHERV',cdstring,ldabort=llabort)
433 ENDIF
434 DEALLOCATE(irecvdispl)
435 
436 END SUBROUTINE mpl_allgatherv_int_scalar
437 
438 END MODULE mpl_allgatherv_mod
subroutine, public mpl_message(KERROR, CDMESSAGE, CDSTRING, LDABORT)
integer(kind=jpim), parameter jp_blocking_buffered
integer, parameter jpim
Definition: parkind1.F90:13
integer, parameter jprd
Definition: parkind1.F90:39
subroutine, public mpl_recvstats(ICOUNT, ITYPE)
integer(kind=jpim) mpl_numproc
logical lmplstats
Definition: yommplstats.F90:17
integer(kind=jpim), parameter jp_non_blocking_standard
integer(kind=jpim), dimension(:), allocatable mpl_comm_oml
integer(kind=jpim), parameter jp_blocking_standard
subroutine, public mpl_sendstats(ICOUNT, ITYPE)
subroutine mpl_allgatherv_real8(PSENDBUF, PRECVBUF, KRECVCOUNTS, KRECVDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
integer(kind=jpim), parameter jp_non_blocking_buffered
subroutine mpl_allgatherv_int_scalar(KSENDBUF, KRECVBUF, KRECVCOUNTS, KRECVDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
integer, parameter jprm
Definition: parkind1.F90:30
intent(out) overrides sub arrays one Sort by the least significant key first sum(iindex(1:n))
integer(kind=jpim) mpl_method
subroutine mpl_allgatherv_real4(PSENDBUF, PRECVBUF, KRECVCOUNTS, KRECVDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
integer(kind=jpim) mpl_unit
subroutine mpl_allgatherv_int(KSENDBUF, KRECVBUF, KRECVCOUNTS, KRECVDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
integer(kind=jpim) mpl_output