SURFEX v8.1
General documentation of Surfex
mpl_alltoallv_mod.F90
Go to the documentation of this file.
2 
3 !**** MPL_ALLTOALLV - Everyone sends different data to everyone
4 
5 ! Purpose.
6 ! --------
7 ! Interface to MPI_ALLTOALLV
8 
9 ! The data may be REAL*8,or INTEGER
10 
11 !** Interface.
12 ! ----------
13 ! CALL MPL_ALLTOALLV
14 
15 ! Input required arguments :
16 ! -------------------------
17 ! PSENDBUF - buffer containing message
18 ! (can be type REAL*8 or INTEGER)
19 ! PRECVBUF - buffer containing message
20 ! (can be type REAL*8 or INTEGER)
21 ! KRECVCOUNTS-number of elements received from each process
22 ! KSENDCOUNTS-number of elements to be sent to each process
23 
24 ! Input optional arguments :
25 ! -------------------------
26 ! KCOMM - Communicator number if different from MPI_COMM_WORLD
27 ! or from that established as the default
28 ! by an MPL communicator routine
29 ! KRECVDISPL -displacements in PRECVBUF at which to place
30 ! the incoming data
31 ! KSENDDISPL -displacements in PSENDBUF from which to send
32 ! the data
33 ! KMP_TYPE - buffering type (see MPL_BUFFER_METHOD)
34 ! overrides value provided to MPL_BUFFER_METHOD
35 ! CDSTRING - Character string for ABORT messages
36 ! used when KERROR is not provided
37 
38 ! Output optional arguments :
39 ! -------------------------
40 ! KREQUEST - Communication request
41 ! required when buffering type is non-blocking
42 ! KERROR - return error code. If not supplied,
43 ! MPL_ALLTOALLV aborts when an error is detected.
44 
45 ! Author.
46 ! -------
47 ! Y. Tremolet
48 
49 ! Modifications.
50 ! --------------
51 ! Original: 02-03-21
52 ! Modified : 25-09-02 M.Hamrud - generalize
53 ! F. Vana 05-Mar-2015 Support for single precision
54 ! ------------------------------------------------------------------
55 
56 USE parkind1 ,ONLY : jprd, jpim, jpib, jprm
57 
58 USE mpl_mpif
61 USE mpl_stats_mod
62 USE yommplstats
63 
64 IMPLICIT NONE
65 PRIVATE
66 
67 LOGICAL :: llabort=.true.
69 LOGICAL :: llscalar
70 
71 INTERFACE mpl_alltoallv
73 END INTERFACE
74 
75 PUBLIC mpl_alltoallv
76 
77 CONTAINS
78 ! ------------------------------------------------------------------
79 
80 SUBROUTINE mpl_alltoallv_preamb(KSENDCOUNTS,KISENDDISPL,&
81  & KRECVCOUNTS,KIRECVDISPL,KSENDDISPL,KRECVDISPL,KMP_TYPE,KCOMM,CDSTRING)
82 
83 
84 #ifdef USE_8_BYTE_WORDS
85  USE mpi4to8, ONLY : &
86  mpi_comm_size => mpi_comm_size8
87 #endif
88 
89 
90 INTEGER(KIND=JPIM),INTENT(IN) :: KRECVCOUNTS(:),KSENDCOUNTS(:)
91 INTEGER(KIND=JPIM),INTENT(OUT) :: KISENDDISPL(:),KIRECVDISPL(:)
92 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KSENDDISPL(:),KRECVDISPL(:),KCOMM,KMP_TYPE
93 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
94 INTEGER(KIND=JPIM) :: ITID,J
95 itid = oml_my_thread()
96 IF(mpl_numproc < 1) CALL mpl_message( &
97  & cdmessage='MPL_ALLTOALLV: MPL NOT INITIALISED ',ldabort=llabort)
98 
99 IF(PRESENT(kcomm)) THEN
100  icomm=kcomm
101 ELSE
102  icomm=mpl_comm_oml(itid)
103 ENDIF
104 
105 IF(PRESENT(kmp_type)) THEN
106  imp_type=kmp_type
107 ELSE
109 ENDIF
110 
111 IF(icomm == mpl_comm_oml(itid)) THEN
113 ELSE
114  CALL mpi_comm_size(icomm,ipl_numproc,ierror)
115 ENDIF
116 
117 IF(SIZE(krecvcounts) < ipl_numproc) THEN
118  WRITE(mpl_errunit,*)'MPL_ALLTOALLV: ERROR KRECVCOUNTS dimension=',&
119  & SIZE(krecvcounts)
120  CALL mpl_message(cdmessage=&
121  & 'MPL_ALLTOALLV: ERROR KRECVCOUNTS dimension is wrong',ldabort=llabort)
122 ENDIF
123 
124 IF(SIZE(ksendcounts) < ipl_numproc) THEN
125  WRITE(mpl_errunit,*)'MPL_ALLTOALLV: ERROR KSENDCOUNTS dimension=',&
126  & SIZE(ksendcounts)
127  CALL mpl_message(cdmessage=&
128  & 'MPL_ALLTOALLV: ERROR KSENDCOUNTS dimension is wrong',ldabort=llabort)
129 ENDIF
130 
131 IF(PRESENT(krecvdispl)) THEN
132  DO j=1,min(SIZE(krecvdispl),SIZE(kirecvdispl))
133  kirecvdispl(j) = krecvdispl(j)
134  ENDDO
135 ELSE
136  kirecvdispl(:) = 0
137  IF(llscalar) THEN
138  DO ir=2, ipl_numproc
139  kirecvdispl(ir) = kirecvdispl(ir-1) + 1
140  ENDDO
141  ELSE
142  DO ir=2, ipl_numproc
143  kirecvdispl(ir) = kirecvdispl(ir-1) + krecvcounts(ir-1)
144  ENDDO
145  ENDIF
146 ENDIF
147 
148 DO ir=1, ipl_numproc
149  IF(kirecvdispl(ir) < 0 .OR. krecvcounts(ir) < 0) THEN
150  WRITE(mpl_errunit,'(A,4I10)')'MPL_ALLTOALLV: RECV.. < 0 ',&
151  & ir,kirecvdispl(ir),krecvcounts(ir)
152  CALL mpl_message(ierror,'MPL_ALLTOALLV',cdstring,ldabort=llabort)
153  ENDIF
154  IF(kirecvdispl(ir)+krecvcounts(ir) > irecvcount) THEN
155  WRITE(mpl_errunit,'(A,4I10)')'MPL_ALLTOALLV:RECV BUFFER TOO SMALL ', &
156  & ir,kirecvdispl(ir),krecvcounts(ir),irecvcount
157  CALL mpl_message(ierror,'MPL_ALLTOALLV',cdstring,ldabort=llabort)
158  ENDIF
159 ENDDO
160 
161 IF(PRESENT(ksenddispl)) THEN
162  DO j=1,min(SIZE(ksenddispl),SIZE(kisenddispl))
163  kisenddispl(j) = ksenddispl(j)
164  ENDDO
165 ELSE
166  kisenddispl(:) = 0
167  IF(llscalar) THEN
168  DO ir=2, ipl_numproc
169  kisenddispl(ir) = kisenddispl(ir-1) + 1
170  ENDDO
171  ELSE
172  DO ir=2, ipl_numproc
173  kisenddispl(ir) = kisenddispl(ir-1) + ksendcounts(ir-1)
174  ENDDO
175  ENDIF
176 ENDIF
177 DO ir=1, ipl_numproc
178  IF(kisenddispl(ir) < 0 .OR. ksendcounts(ir) < 0) THEN
179  WRITE(mpl_errunit,'(A,4I10)')'MPL_ALLTOALLV:SEND.. <0 ',&
180  & ir,kisenddispl(ir),ksendcounts(ir)
181  CALL mpl_message(ierror,'MPL_ALLTOALLV',cdstring,ldabort=llabort)
182  ENDIF
183  IF(kisenddispl(ir)+ksendcounts(ir) > isendcount) THEN
184  WRITE(mpl_errunit,'(A,4I10)')'MPL_ALLTOALLV:SEND BUFFER TOO SMALL ', &
185  & ir,kisenddispl(ir),ksendcounts(ir),isendcount
186  CALL mpl_message(ierror,'MPL_ALLTOALLV',cdstring,ldabort=llabort)
187  ENDIF
188 ENDDO
189 
190 END SUBROUTINE mpl_alltoallv_preamb
191 
192 SUBROUTINE mpl_alltoallv_real8(PSENDBUF,KSENDCOUNTS,PRECVBUF,KRECVCOUNTS,&
193  &KSENDDISPL,KRECVDISPL,KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
195 
196 #ifdef USE_8_BYTE_WORDS
197  USE mpi4to8, ONLY : &
198  mpi_alltoallv => mpi_alltoallv8
199 #endif
200 
201 
202 IMPLICIT NONE
203 INTEGER(KIND=JPIM), INTENT(IN) :: KSENDCOUNTS(:), KRECVCOUNTS(:)
204 REAL(KIND=JPRD), INTENT(IN) :: PSENDBUF(:)
205 REAL(KIND=JPRD), INTENT(OUT) :: PRECVBUF(:)
206 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KSENDDISPL(:), KRECVDISPL(:), KCOMM ,KMP_TYPE
207 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
208 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
209 
210 INTEGER(KIND=JPIM) :: IRECVDISPL(mpl_numproc),ISENDDISPL(mpl_numproc)
211 
212 isendcount=SIZE(psendbuf)
213 irecvcount=SIZE(precvbuf)
214 
215 #ifndef NAG
216 IF (isendcount > 0) THEN
217  IF( (loc(psendbuf(ubound(psendbuf,1))) - loc(psendbuf(lbound(psendbuf,1)))) /= 8_jpib*(isendcount - 1) .AND. &
218  & isendcount > 0 ) THEN
219  CALL mpl_message(cdmessage='MPL_ALLTOALLV: SENDBUF NOT CONTIGUOUS ',ldabort=llabort)
220  ENDIF
221 ENDIF
222 
223 IF (irecvcount > 0) THEN
224  IF( (loc(precvbuf(ubound(precvbuf,1))) - loc(precvbuf(lbound(precvbuf,1)))) /= 8_jpib*(irecvcount - 1) .AND. &
225  & irecvcount > 0 ) THEN
226  CALL mpl_message(cdmessage='MPL_ALLTOALLV: RECVBUF NOT CONTIGUOUS ',ldabort=llabort)
227  ENDIF
228 ENDIF
229 #endif
230 
231 llscalar=.false.
232 
233 ierror=0
234 CALL mpl_alltoallv_preamb(ksendcounts,isenddispl,&
235  & krecvcounts,irecvdispl,ksenddispl,krecvdispl,kmp_type,kcomm,cdstring)
237  CALL mpi_alltoallv(psendbuf(:),ksendcounts,isenddispl,int(mpi_real8), &
238  & precvbuf(:),krecvcounts,irecvdispl,int(mpi_real8),icomm,ierror)
240  IF(.NOT.PRESENT(krequest)) CALL mpl_message(kerror,'MPL_ALLTOALLV',' KREQUEST MISSING',ldabort=llabort)
241  CALL mpi_ialltoallv(psendbuf(:),ksendcounts,isenddispl,int(mpi_real8), &
242  & precvbuf(:),krecvcounts,irecvdispl,int(mpi_real8),icomm,krequest,ierror)
243 ELSE
244  IF(PRESENT(kerror)) THEN
245  ierror=1
246  ELSE
247  CALL mpl_message(kerror,'MPL_ALLTOALLV',' INVALID METHOD',ldabort=llabort)
248  ENDIF
249 ENDIF
250 
251 IF(PRESENT(kerror)) THEN
252  kerror=ierror
253 ELSE
254  IF (ierror/=0) CALL mpl_message(ierror,'ERROR IN MPL_ALLTOALLV',&
255  &ldabort=llabort)
256 ENDIF
257 
258 IF(lmplstats) THEN
259  CALL mpl_sendstats(sum(ksendcounts),int(mpi_real8))
260  CALL mpl_recvstats(sum(krecvcounts),int(mpi_real8))
261 ENDIF
262 
263 END SUBROUTINE mpl_alltoallv_real8
264 
265 SUBROUTINE mpl_alltoallv_real4(PSENDBUF,KSENDCOUNTS,PRECVBUF,KRECVCOUNTS,&
266  &KSENDDISPL,KRECVDISPL,KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
268 
269 #ifdef USE_8_BYTE_WORDS
270  USE mpi4to8, ONLY : &
271  mpi_alltoallv => mpi_alltoallv8
272 #endif
273 
274 
275 IMPLICIT NONE
276 INTEGER(KIND=JPIM), INTENT(IN) :: KSENDCOUNTS(:), KRECVCOUNTS(:)
277 REAL(KIND=JPRM), INTENT(IN) :: PSENDBUF(:)
278 REAL(KIND=JPRM), INTENT(OUT) :: PRECVBUF(:)
279 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KSENDDISPL(:), KRECVDISPL(:), KCOMM ,KMP_TYPE
280 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
281 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
282 
283 INTEGER(KIND=JPIM) :: IRECVDISPL(mpl_numproc),ISENDDISPL(mpl_numproc)
284 
285 isendcount=SIZE(psendbuf)
286 irecvcount=SIZE(precvbuf)
287 
288 #ifndef NAG
289 IF (isendcount > 0) THEN
290  IF( (loc(psendbuf(ubound(psendbuf,1))) - loc(psendbuf(lbound(psendbuf,1)))) /= 4_jpib*(isendcount - 1) ) THEN
291  CALL mpl_message(cdmessage='MPL_ALLTOALLV: SENDBUF NOT CONTIGUOUS ',ldabort=llabort)
292  ENDIF
293 ENDIF
294 
295 IF (irecvcount > 0) THEN
296  IF( (loc(precvbuf(ubound(precvbuf,1))) - loc(precvbuf(lbound(precvbuf,1)))) /= 4_jpib*(irecvcount - 1) ) THEN
297  CALL mpl_message(cdmessage='MPL_ALLTOALLV: RECVBUF NOT CONTIGUOUS ',ldabort=llabort)
298  ENDIF
299 ENDIF
300 #endif
301 
302 llscalar=.false.
303 
304 ierror=0
305 CALL mpl_alltoallv_preamb(ksendcounts,isenddispl,&
306  & krecvcounts,irecvdispl,ksenddispl,krecvdispl,kmp_type,kcomm,cdstring)
308  CALL mpi_alltoallv(psendbuf(:),ksendcounts,isenddispl,int(mpi_real4), &
309  & precvbuf(:),krecvcounts,irecvdispl,int(mpi_real4),icomm,ierror)
311  CALL mpi_ialltoallv(psendbuf(:),ksendcounts,isenddispl,int(mpi_real4), &
312  & precvbuf(:),krecvcounts,irecvdispl,int(mpi_real4),icomm,krequest,ierror)
313 ELSE
314  IF(PRESENT(kerror)) THEN
315  ierror=1
316  ELSE
317  CALL mpl_message(kerror,'MPL_ALLTOALLV',' INVALID METHOD',ldabort=llabort)
318  ENDIF
319 ENDIF
320 
321 IF(PRESENT(kerror)) THEN
322  kerror=ierror
323 ELSE
324  IF (ierror/=0) CALL mpl_message(ierror,'ERROR IN MPL_ALLTOALLV',&
325  &ldabort=llabort)
326 ENDIF
327 
328 IF(lmplstats) THEN
329  CALL mpl_sendstats(sum(ksendcounts),int(mpi_real4))
330  CALL mpl_recvstats(sum(krecvcounts),int(mpi_real4))
331 ENDIF
332 
333 END SUBROUTINE mpl_alltoallv_real4
334 
335 
336 SUBROUTINE mpl_alltoallv_integer(KSENDBUF,KSENDCOUNTS,KRECVBUF,KRECVCOUNTS,&
337  &KSENDDISPL,KRECVDISPL,KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
339 
340 #ifdef USE_8_BYTE_WORDS
341  USE mpi4to8, ONLY : &
342  mpi_alltoallv => mpi_alltoallv8
343 #endif
344 
345 
346 IMPLICIT NONE
347 INTEGER(KIND=JPIM), INTENT(IN) :: KSENDCOUNTS(:), KRECVCOUNTS(:)
348 INTEGER(KIND=JPIM), INTENT(IN) :: KSENDBUF(:)
349 INTEGER(KIND=JPIM), INTENT(OUT) :: KRECVBUF(:)
350 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KSENDDISPL(:), KRECVDISPL(:), KCOMM,KMP_TYPE
351 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
352 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KREQUEST,KERROR
353 
354 INTEGER(KIND=JPIM) :: IRECVDISPL(mpl_numproc),ISENDDISPL(mpl_numproc)
355 
356 isendcount=SIZE(ksendbuf)
357 irecvcount=SIZE(krecvbuf)
358 
359 #ifndef NAG
360 IF (isendcount > 0) THEN
361  IF( (loc(ksendbuf(ubound(ksendbuf,1))) - loc(ksendbuf(lbound(ksendbuf,1)))) /= 4_jpib*(isendcount - 1) ) THEN
362  CALL mpl_message(cdmessage='MPL_ALLTOALLV: SENDBUF NOT CONTIGUOUS ',ldabort=llabort)
363  ENDIF
364 ENDIF
365 
366 IF (irecvcount > 0) THEN
367  IF( (loc(krecvbuf(ubound(krecvbuf,1))) - loc(krecvbuf(lbound(krecvbuf,1)))) /= 4_jpib*(irecvcount - 1) ) THEN
368  CALL mpl_message(cdmessage='MPL_ALLTOALLV: RECVBUF NOT CONTIGUOUS ',ldabort=llabort)
369  ENDIF
370 ENDIF
371 #endif
372 
373 llscalar=.false.
374 
375 ierror=0
376 CALL mpl_alltoallv_preamb(ksendcounts,isenddispl,&
377  & krecvcounts,irecvdispl,ksenddispl,krecvdispl,kmp_type,kcomm,cdstring)
379  CALL mpi_alltoallv(ksendbuf(1),ksendcounts,isenddispl,int(mpi_integer), &
380  & krecvbuf(1),krecvcounts,irecvdispl,int(mpi_integer),icomm,ierror)
382  IF(.NOT.PRESENT(krequest)) CALL mpl_message(kerror,'MPL_ALLTOALLV',' KREQUEST MISSING',ldabort=llabort)
383  CALL mpi_ialltoallv(ksendbuf(1),ksendcounts,isenddispl,int(mpi_integer), &
384  & krecvbuf(1),krecvcounts,irecvdispl,int(mpi_integer),icomm,krequest,ierror)
385 ELSE
386  IF(PRESENT(kerror)) THEN
387  ierror=1
388  ELSE
389  CALL mpl_message(kerror,'MPL_ALLTOALLV',' INVALID METHOD',ldabort=llabort)
390  ENDIF
391 ENDIF
392 
393 IF(PRESENT(kerror)) THEN
394  kerror=ierror
395 ELSE
396  IF (ierror/=0) CALL mpl_message(ierror,'ERROR IN MPL_ALLTOALLV',&
397  &ldabort=llabort)
398 ENDIF
399 
400 IF(lmplstats) THEN
401  CALL mpl_sendstats(sum(ksendcounts),int(mpi_integer))
402  CALL mpl_recvstats(sum(krecvcounts),int(mpi_integer))
403 ENDIF
404 
405 END SUBROUTINE mpl_alltoallv_integer
406 
407 ! ------------------------------------------------------------------
408 
409 END MODULE mpl_alltoallv_mod
410 
411 
integer(kind=jpim) icomm
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) ir
integer(kind=jpim) mpl_numproc
subroutine mpl_alltoallv_preamb(KSENDCOUNTS, KISENDDISPL, KRECVCOUNTS, KIRECVDISPL, KSENDDISPL, KRECVDISPL, KMP_TYPE, KCOMM, CDSTRING)
integer(kind=jpim) imp_type
logical lmplstats
Definition: yommplstats.F90:17
integer(kind=jpim), parameter jp_non_blocking_standard
subroutine mpl_alltoallv_real8(PSENDBUF, KSENDCOUNTS, PRECVBUF, KRECVCOUNTS, KSENDDISPL, KRECVDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
integer(kind=jpim), dimension(:), allocatable mpl_comm_oml
integer(kind=jpim), parameter jp_blocking_standard
subroutine, public mpl_sendstats(ICOUNT, ITYPE)
integer(kind=jpim), parameter jp_non_blocking_buffered
integer(kind=jpim) mpl_errunit
integer, parameter jprm
Definition: parkind1.F90:30
integer(kind=jpim) ierror
subroutine mpl_alltoallv_integer(KSENDBUF, KSENDCOUNTS, KRECVBUF, KRECVCOUNTS, KSENDDISPL, KRECVDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
intent(out) overrides sub arrays one Sort by the least significant key first sum(iindex(1:n))
integer(kind=jpim) mpl_method
integer(kind=jpim) isendcount
integer, parameter jpib
Definition: parkind1.F90:14
integer(kind=jpim) ipl_numproc
integer(kind=jpim) irecvcount
subroutine mpl_alltoallv_real4(PSENDBUF, KSENDCOUNTS, PRECVBUF, KRECVCOUNTS, KSENDDISPL, KRECVDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)