SURFEX v8.1
General documentation of Surfex
mpl_allreduce_mod.F90
Go to the documentation of this file.
2 
3 !**** MPL_ALLREDUCE Perform collective communication
4 
5 ! Purpose.
6 ! --------
7 ! To calculate global MIN,MAX,SUM or IEOR and return result to all processes.
8 ! The data may be REAL*4, REAL*8,or INTEGER, one dimensional array or scalar
9 
10 !** Interface.
11 ! ----------
12 ! CALL MPL_ALLREDUCE
13 
14 ! Input required arguments :
15 ! -------------------------
16 ! PSENDBUF - buffer containing message to be collectively communicated
17 ! (can be type REAL*4, REAL*8 or INTEGER) (also output)
18 ! CDOPER - Global operation to be performed : 'MAX', 'MIN', 'SUM' or 'IEOR'
19 
20 ! Input optional arguments :
21 ! -------------------------
22 ! LDREPROD - Reproducibility flag for SUMmation-operator.
23 ! Meaningful only for REAL-numbers.
24 ! Three modes (applicable for REAL-number only):
25 ! 1) Not provided at all (the default) ==> MPL_ABORT
26 ! 2) Provided and .TRUE. ==> Use home-written binary tree
27 ! No MPI_ALLREDUCE used.
28 ! 3) Provided, but .FALSE. ==> let MPI_ALLREDUCE do the summation.
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 ! the incoming data
33 ! CDSTRING - Character string for ABORT messages
34 ! used when KERROR is not provided
35 
36 ! Output required arguments :
37 ! -------------------------
38 ! none
39 
40 ! Output optional arguments :
41 ! -------------------------
42 ! KERROR - return error code. If not supplied,
43 ! MPL_ALLREDUCE aborts when an error is detected.
44 ! Author.
45 ! -------
46 ! D.Dent, M.Hamrud, S.Saarinen ECMWF
47 
48 ! Modifications.
49 ! --------------
50 ! Original: 2001-02-02
51 ! F. Vana 05-Mar-2015 Support for single precision
52 
53 ! ------------------------------------------------------------------
54 
55 USE parkind1 , ONLY : jprd, jpim, jprm, jpib
56 
57 USE mpl_mpif
59 USE mpl_stats_mod
60 USE yommplstats
62 USE mpl_send_mod
63 USE mpl_recv_mod
64 USE mpl_wait_mod
66 
67 IMPLICIT NONE
68 
69 PRIVATE
70 
71 LOGICAL :: llabort=.true.
72 
73 INTERFACE mpl_allreduce
78 END INTERFACE
79 
80 PUBLIC mpl_allreduce
81 
82 CONTAINS
83 
84 SUBROUTINE mpl_allreduce_int_scalar(KSENDBUF,CDOPER,LDREPROD, &
85  & KCOMM,KERROR,CDSTRING)
86 
87 INTEGER(KIND=JPIM),INTENT(INOUT) :: KSENDBUF
88 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
89 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
90 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
91 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
92 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
93 INTEGER(KIND=JPIM) ISENDBUF(1)
94 
95 isendbuf(1) = ksendbuf
96 CALL mpl_allreduce(isendbuf,cdoper,ldreprod,kcomm,kerror,cdstring)
97 ksendbuf = isendbuf(1)
98 
99 END SUBROUTINE mpl_allreduce_int_scalar
100 
101 SUBROUTINE mpl_allreduce_int8_scalar(KSENDBUF,CDOPER,LDREPROD, &
102  & KCOMM,KERROR,CDSTRING)
103 INTEGER(KIND=JPIB),INTENT(INOUT) :: KSENDBUF
104 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
105 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
106 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
107 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
108 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
109 INTEGER(KIND=JPIB) ISENDBUF(1)
110 
111 isendbuf(1) = ksendbuf
112 CALL mpl_allreduce(isendbuf,cdoper,ldreprod,kcomm,kerror,cdstring)
113 ksendbuf = isendbuf(1)
114 
115 END SUBROUTINE mpl_allreduce_int8_scalar
116 
117 
118 
119 SUBROUTINE mpl_allreduce_real8_scalar(PSENDBUF,CDOPER,LDREPROD, &
120  & KCOMM,KERROR,CDSTRING)
121 REAL(KIND=JPRD),INTENT(INOUT) :: PSENDBUF
122 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
123 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
124 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
125 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
126 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
127 REAL(KIND=JPRD) ZSENDBUF(1)
128 
129 zsendbuf(1) = psendbuf
130 CALL mpl_allreduce(zsendbuf,cdoper,ldreprod,kcomm,kerror,cdstring)
131 psendbuf = zsendbuf(1)
132 
133 END SUBROUTINE mpl_allreduce_real8_scalar
134 
135 
136 SUBROUTINE mpl_allreduce_real4_scalar(PSENDBUF,CDOPER,LDREPROD, &
137  & KCOMM,KERROR,CDSTRING)
138 REAL(KIND=JPRM),INTENT(INOUT) :: PSENDBUF
139 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
140 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
141 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
142 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
143 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
144 REAL(KIND=JPRM) ZSENDBUF(1)
145 
146 zsendbuf(1) = psendbuf
147 CALL mpl_allreduce(zsendbuf,cdoper,ldreprod,kcomm,kerror,cdstring)
148 psendbuf = zsendbuf(1)
149 
150 END SUBROUTINE mpl_allreduce_real4_scalar
151 
152 
153 SUBROUTINE mpl_allreduce_int(KSENDBUF,CDOPER,LDREPROD, &
154  & KCOMM,KERROR,CDSTRING)
156 #ifdef USE_8_BYTE_WORDS
157  USE mpi4to8, ONLY : &
158  mpi_allreduce => mpi_allreduce8
159 #endif
160 
161 INTEGER(KIND=JPIM),INTENT(INOUT) :: KSENDBUF(:)
162 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
163 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
164 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
165 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
166 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
167 INTEGER(KIND=JPIM) :: IRECVBUF(size(ksendbuf))
168 INTEGER(KIND=JPIM) :: ISENDCOUNT,ICOMM,IERROR,IOPER
169 INTEGER(KIND=JPIM) :: ITID
170 itid = oml_my_thread()
171 ierror = 0
172 IF(mpl_numproc < 1) CALL mpl_message( &
173  & cdmessage='MPL_ALLREDUCE: MPL NOT INITIALISED ',ldabort=llabort)
174 
175 IF(cdoper(1:3) == 'MAX' .OR. cdoper(1:3) == 'max' ) THEN
176  ioper = mpi_max
177 ELSEIF(cdoper(1:3) == 'MIN' .OR. cdoper(1:3) == 'min' ) THEN
178  ioper = mpi_min
179 ELSEIF(cdoper(1:3) == 'SUM' .OR. cdoper(1:3) == 'sum' ) THEN
180  ioper = mpi_sum
181 ELSEIF(cdoper(1:4) == 'IEOR' .OR. cdoper(1:4) == 'ieor' ) THEN
182  ioper = mpi_bxor
183 ELSEIF(cdoper(1:4) == 'XOR' .OR. cdoper(1:4) == 'xor' ) THEN
184  ioper = mpi_bxor
185 ELSE
186  CALL mpl_message(ierror,'MPL_ALLREDUCE: ERROR UNKNOWN OPERATOR',&
187  & cdstring,ldabort=llabort)
188 ENDIF
189 
190 IF(PRESENT(kcomm)) THEN
191  icomm=kcomm
192 ELSE
193  icomm=mpl_comm_oml(itid)
194 ENDIF
195 
196 isendcount = SIZE(ksendbuf)
197 
198 IF (isendcount > 0) THEN
199 #ifndef NAG
200  IF( (loc(ksendbuf(ubound(ksendbuf,1)))-loc(ksendbuf(lbound(ksendbuf,1)))) /= 4_jpib*(isendcount - 1) ) THEN
201  CALL mpl_message(cdmessage='MPL_ALLREDUCE: BUFFER NOT CONTIGUOUS ',ldabort=llabort)
202  ENDIF
203 ENDIF
204 #endif
205 
206 IF ( mpl_numproc > 1 ) &
207 CALL mpi_allreduce(ksendbuf,irecvbuf,isendcount,int(mpi_integer), &
208  & ioper,icomm,ierror)
209 
210 IF(lmplstats) THEN
211  CALL mpl_sendstats(isendcount,int(mpi_integer))
212  CALL mpl_recvstats(isendcount,int(mpi_integer))
213 ENDIF
214 
215 IF(mpl_output > 1 )THEN
216  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLREDUCE ',isendcount,icomm,ioper
217 ENDIF
218 IF(PRESENT(kerror)) THEN
219  kerror=ierror
220 ELSE
221  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLREDUCE',cdstring,ldabort=llabort)
222 ENDIF
223 
224 IF ( mpl_numproc > 1 ) &
225 ksendbuf(:) = irecvbuf(:)
226 
227 END SUBROUTINE mpl_allreduce_int
228 
229 SUBROUTINE mpl_allreduce_int8(KSENDBUF,CDOPER,LDREPROD, &
230  & KCOMM,KERROR,CDSTRING)
231 INTEGER(KIND=JPIB),INTENT(INOUT) :: KSENDBUF(:)
232 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
233 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
234 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
235 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
236 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
237 INTEGER(KIND=JPIB) :: IRECVBUF(size(ksendbuf))
238 INTEGER(KIND=JPIM) :: ISENDCOUNT,ICOMM,IERROR,IOPER
239 INTEGER(KIND=JPIM) :: ITID
240 ierror = 0
241 itid = oml_my_thread()
242 IF(mpl_numproc < 1) CALL mpl_message( &
243  & cdmessage='MPL_ALLREDUCE: MPL NOT INITIALISED ',ldabort=llabort)
244 
245 IF(cdoper(1:3) == 'MAX' .OR. cdoper(1:3) == 'max' ) THEN
246  ioper = mpi_max
247 ELSEIF(cdoper(1:3) == 'MIN' .OR. cdoper(1:3) == 'min' ) THEN
248  ioper = mpi_min
249 ELSEIF(cdoper(1:3) == 'SUM' .OR. cdoper(1:3) == 'sum' ) THEN
250  ioper = mpi_sum
251 ELSEIF(cdoper(1:4) == 'IEOR' .OR. cdoper(1:4) == 'ieor' ) THEN
252  ioper = mpi_bxor
253 ELSEIF(cdoper(1:4) == 'XOR' .OR. cdoper(1:4) == 'xor' ) THEN
254  ioper = mpi_bxor
255 ELSE
256  CALL mpl_message(ierror,'MPL_ALLREDUCE: ERROR UNKNOWN OPERATOR',&
257  & cdstring,ldabort=llabort)
258 ENDIF
259 
260 IF(PRESENT(kcomm)) THEN
261  icomm=kcomm
262 ELSE
263  icomm=mpl_comm_oml(itid)
264 ENDIF
265 
266 isendcount = SIZE(ksendbuf)
267 #ifndef NAG
268 IF (isendcount > 0) THEN
269  IF( (loc(ksendbuf(ubound(ksendbuf,1)))-loc(ksendbuf(lbound(ksendbuf,1)))) /= 8_jpib*(isendcount - 1) ) THEN
270  CALL mpl_message(cdmessage='MPL_ALLREDUCE: BUFFER NOT CONTIGUOUS ',ldabort=llabort)
271  ENDIF
272 ENDIF
273 #endif
274 
275 IF ( mpl_numproc > 1 ) &
276 CALL mpi_allreduce(ksendbuf,irecvbuf,isendcount,mpi_integer8, &
277  & ioper,icomm,ierror)
278 
279 IF(lmplstats) THEN
280  CALL mpl_sendstats(isendcount,int(mpi_integer8))
281  CALL mpl_recvstats(isendcount,int(mpi_integer8))
282 ENDIF
283 
284 IF(mpl_output > 1 )THEN
285  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLREDUCE ',isendcount,icomm,ioper
286 ENDIF
287 IF(PRESENT(kerror)) THEN
288  kerror=ierror
289 ELSE
290  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLREDUCE',cdstring,ldabort=llabort)
291 ENDIF
292 
293 IF ( mpl_numproc > 1 ) &
294 ksendbuf(:) = irecvbuf(:)
295 
296 END SUBROUTINE mpl_allreduce_int8
297 
298 
299 SUBROUTINE mpl_allreduce_real8(PSENDBUF,CDOPER,LDREPROD, &
300  & KCOMM,KERROR,CDSTRING)
302 
303 #ifdef USE_8_BYTE_WORDS
304  USE mpi4to8, ONLY : &
305  mpi_allreduce => mpi_allreduce8
306 #endif
307 
308 REAL(KIND=JPRD),INTENT(INOUT) :: PSENDBUF(:)
309 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
310 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
311 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
312 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
313 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
314 REAL(KIND=JPRD) :: ZRECVBUF(size(psendbuf))
315 INTEGER(KIND=JPIM) ITAG, ICOUNT
316 LOGICAL LLREPRODSUM
317 INTEGER(KIND=JPIM) :: ISENDCOUNT,ICOMM,IERROR,IOPER
318 INTEGER(KIND=JPIM) :: IP2,II,IHALF,JSTAGE,ISEND,IRECV,IMSENT
319 INTEGER(KIND=JPIM) :: ISREQ(mpl_numproc)
320 INTEGER(KIND=JPIM) :: ITID
321 ierror = 0
322 itid = oml_my_thread()
323 llreprodsum = .false.
324 
325 IF(mpl_numproc < 1) CALL mpl_message( &
326  & cdmessage='MPL_ALLREDUCE: MPL NOT INITIALISED ',ldabort=llabort)
327 
328 IF(cdoper(1:3) == 'MAX' .OR. cdoper(1:3) == 'max' ) THEN
329  ioper = mpi_max
330 ELSEIF(cdoper(1:3) == 'MIN' .OR. cdoper(1:3) == 'min' ) THEN
331  ioper = mpi_min
332 ELSEIF(cdoper(1:3) == 'SUM' .OR. cdoper(1:3) == 'sum' ) THEN
333  ioper = mpi_sum
334  IF (PRESENT(ldreprod)) THEN
335  llreprodsum = ldreprod
336  ELSE
337  CALL mpl_message(ierror,&
338  & 'MPL_ALLREDUCE: SUMMATION OPERATOR NOT REPRODUCIBLE IN REAL MODE',&
339  & cdstring,ldabort=llabort)
340  ENDIF
341 ELSE
342  CALL mpl_message(ierror,'MPL_ALLREDUCE: ERROR UNKNOWN OPERATOR',&
343  & cdstring,ldabort=llabort)
344 ENDIF
345 
346 IF(PRESENT(kcomm)) THEN
347  icomm=kcomm
348 ELSE
349  icomm=mpl_comm_oml(itid)
350 ENDIF
351 
352 isendcount = SIZE(psendbuf)
353 #ifndef NAG
354 IF (isendcount > 0) THEN
355  IF( (loc(psendbuf(ubound(psendbuf,1)))-loc(psendbuf(lbound(psendbuf,1)))) /= 8_jpib*(isendcount - 1) ) THEN
356  CALL mpl_message(cdmessage='MPL_ALLREDUCE: BUFFER NOT CONTIGUOUS ',ldabort=llabort)
357  ENDIF
358 ENDIF
359 #endif
360 
361 IF (llreprodsum) THEN
362 !-- Near reproducible summation (independent of number of threads)
363 
364  ip2=0
365  DO
366  ip2=ip2+1
367  IF(2**ip2 >= mpl_numproc) EXIT
368  ENDDO
369 
370  imsent=0
371  DO jstage=ip2,1,-1
372 ! WRITE(0,*) 'STAGE ',JSTAGE
373  itag = 2001+jstage
374  ii = 2**jstage
375  ihalf = ii/2
376  isend = mpl_rank - ihalf
377  IF(isend > 0 .AND. mpl_rank <= ii) THEN
378  imsent=imsent+1
379  CALL mpl_send(psendbuf,kdest=isend,kcomm=icomm,ktag=itag,kerror=ierror,&
380  &kmp_type=jp_non_blocking_standard,krequest=isreq(imsent),cdstring='MPLS_SEND')
381 ! write(0,*) 'I SEND TO ',MPL_RANK,ISEND
382  ENDIF
383  irecv=mpl_rank + ihalf
384  IF(irecv <=mpl_numproc .AND. mpl_rank <= ihalf) THEN
385  CALL mpl_recv(zrecvbuf,ksource=irecv,kcomm=icomm,ktag=itag,&
386  &kerror=ierror,kount=icount)
387 ! write(0,*) 'I RECV FROM ',MPL_RANK,IRECV
388  psendbuf(:) = psendbuf(:) + zrecvbuf(:)
389  ENDIF
390  ENDDO
391  IF(imsent > 0) THEN
392  CALL mpl_wait(psendbuf,krequest=isreq(1:imsent),cdstring='MPLS_SEND')
393  ENDIF
394  IF (mpl_rank == 1) THEN
395  zrecvbuf(:) = psendbuf(:)
396  ENDIF
397 ! write(0,*) 'enter broadcast '
398  CALL mpl_broadcast(zrecvbuf,ktag=itag,kcomm=icomm,kroot=1,kerror=ierror)
399 ! write(0,*) 'exit broadcast '
400 
401 !!$ IMSENT=0
402 !!$ DO JSTAGE=1,IP2
403 !!$ ITAG = 2001+JSTAGE
404 !!$ WRITE(0,*) 'STAGE BACK ',JSTAGE
405 !!$ II = 2**JSTAGE
406 !!$ IHALF = II/2
407 !!$ ISEND=MPL_RANK + IHALF
408 !!$ IF(ISEND <=MPL_NUMPROC .AND. MPL_RANK <= IHALF) THEN
409 !!$ IMSENT=IMSENT+1
410 !!$ CALL MPL_SEND(PSENDBUF,KDEST=ISEND,KCOMM=ICOMM,KTAG=ITAG,KERROR=IERROR,&
411 !!$ &KMP_TYPE=JP_NON_BLOCKING_STANDARD,KREQUEST=ISREQ(IMSENT),CDSTRING='MPLS_SEND')
412 !!$ WRITE(0,*) 'I SEND BACK TO ',MPL_RANK,ISEND
413 !!$ ENDIF
414 !!$ IRECV=MPL_RANK - IHALF
415 !!$ IF(IRECV > 0 .AND. MPL_RANK <= II) THEN
416 !!$ WRITE(0,*) 'I RECV BACK FROM ',MPL_RANK,IRECV
417 !!$ CALL MPL_RECV(ZRECVBUF,KSOURCE=IRECV,KCOMM=ICOMM,KTAG=ITAG,&
418 !!$ &KERROR=IERROR,KOUNT=ICOUNT)
419 !!$ ENDIF
420 !!$ ENDDO
421 !!$ IF(IMSENT > 0) THEN
422 !!$ CALL MPL_WAIT(PSENDBUF,KREQUEST=ISREQ(1:IMSENT),CDSTRING='MPLS_SEND')
423 !!$ ENDIF
424 
425 ELSE
426  IF ( mpl_numproc > 1 ) &
427  CALL mpi_allreduce(psendbuf,zrecvbuf,isendcount,int(mpi_real8), &
428  & ioper,icomm,ierror)
429 
430  IF(lmplstats) THEN
431  CALL mpl_sendstats(isendcount,int(mpi_real8))
432  CALL mpl_recvstats(isendcount,int(mpi_real8))
433  ENDIF
434 
435 ENDIF
436 
437 IF(mpl_output > 1 )THEN
438  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLREDUCE ',isendcount,icomm,ioper
439 ENDIF
440 IF(PRESENT(kerror)) THEN
441  kerror=ierror
442 ELSE
443  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLREDUCE',cdstring,ldabort=llabort)
444 ENDIF
445 
446 IF ( mpl_numproc > 1 ) &
447 psendbuf(:) = zrecvbuf(:)
448 
449 END SUBROUTINE mpl_allreduce_real8
450 
451 
452 SUBROUTINE mpl_allreduce_real4(PSENDBUF,CDOPER,LDREPROD, &
453  & KCOMM,KERROR,CDSTRING)
455 
456 #ifdef USE_8_BYTE_WORDS
457  USE mpi4to8, ONLY : &
458  mpi_allreduce => mpi_allreduce8
459 #endif
460 
461 REAL(KIND=JPRM),INTENT(INOUT) :: PSENDBUF(:)
462 CHARACTER(LEN=*),INTENT(IN) :: CDOPER
463 LOGICAL,INTENT(IN),OPTIONAL :: LDREPROD
464 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
465 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR
466 CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: CDSTRING
467 REAL(KIND=JPRM) :: ZRECVBUF(size(psendbuf))
468 INTEGER(KIND=JPIM) IPROC, ITAG, ICOUNT
469 LOGICAL LLREPRODSUM
470 INTEGER(KIND=JPIM) :: ISENDCOUNT,ICOMM,IERROR,IOPER
471 INTEGER(KIND=JPIM) :: ITID
472 ierror = 0
473 itid = oml_my_thread()
474 llreprodsum = .false.
475 
476 IF(mpl_numproc < 1) CALL mpl_message( &
477  & cdmessage='MPL_ALLREDUCE: MPL NOT INITIALISED ',ldabort=llabort)
478 
479 IF(cdoper(1:3) == 'MAX' .OR. cdoper(1:3) == 'max' ) THEN
480  ioper = mpi_max
481 ELSEIF(cdoper(1:3) == 'MIN' .OR. cdoper(1:3) == 'min' ) THEN
482  ioper = mpi_min
483 ELSEIF(cdoper(1:3) == 'SUM' .OR. cdoper(1:3) == 'sum' ) THEN
484  ioper = mpi_sum
485  IF (PRESENT(ldreprod)) THEN
486  llreprodsum = ldreprod
487  ELSE
488  CALL mpl_message(ierror,&
489  & 'MPL_ALLREDUCE: SUMMATION OPERATOR NOT REPRODUCIBLE IN REAL MODE',&
490  & cdstring,ldabort=llabort)
491  ENDIF
492 ELSE
493  CALL mpl_message(ierror,'MPL_ALLREDUCE: ERROR UNKNOWN OPERATOR',&
494  & cdstring,ldabort=llabort)
495 ENDIF
496 
497 IF(PRESENT(kcomm)) THEN
498  icomm=kcomm
499 ELSE
500  icomm=mpl_comm_oml(itid)
501 ENDIF
502 
503 isendcount = SIZE(psendbuf)
504 #ifndef NAG
505 IF (isendcount > 0) THEN
506  IF( (loc(psendbuf(ubound(psendbuf,1)))-loc(psendbuf(lbound(psendbuf,1)))) /= 4_jpib*(isendcount - 1) ) THEN
507  CALL mpl_message(cdmessage='MPL_ALLREDUCE: BUFFER NOT CONTIGUOUS ',ldabort=llabort)
508  ENDIF
509 ENDIF
510 #endif
511 
512 IF (llreprodsum) THEN
513 !-- Near reproducible summation
514  itag = 2001
515  IF (mpl_rank == 1) THEN
516  DO iproc=2,mpl_numproc
517  CALL mpl_recv(zrecvbuf,ksource=iproc,kcomm=icomm,ktag=itag,&
518  &kerror=ierror,kount=icount)
519  IF (icount /= isendcount) THEN
520  WRITE(mpl_errunit,'(A,I10,A,I6,A,I10)')&
521  & 'MPL_ALLREDUCE: RECEIVED UNEXPECTED NUMBER OF ELEMENTS ', &
522  & icount,' FROM PROC ',iproc,'. EXPECTED=',isendcount
523  CALL mpl_message(ierror,'MPL_ALLREDUCE',cdstring,ldabort=llabort)
524  ENDIF
525  psendbuf(:) = psendbuf(:) + zrecvbuf(:)
526  ENDDO
527  zrecvbuf(:) = psendbuf(:)
528  ELSE
529  CALL mpl_send(psendbuf,kdest=1,kcomm=icomm,ktag=itag,kerror=ierror,&
530  &kmp_type=jp_blocking_standard,cdstring='MPLS_SEND')
531  ENDIF
532  itag = itag + 1
533  CALL mpl_broadcast(zrecvbuf,ktag=itag,kcomm=icomm,kroot=1,kerror=ierror)
534 ELSE
535  IF ( mpl_numproc > 1 ) &
536  CALL mpi_allreduce(psendbuf,zrecvbuf,isendcount,int(mpi_real4), &
537  & ioper,icomm,ierror)
538 
539  IF(lmplstats) THEN
540  CALL mpl_sendstats(isendcount,int(mpi_real4))
541  CALL mpl_recvstats(isendcount,int(mpi_real4))
542  ENDIF
543 
544 ENDIF
545 
546 IF(mpl_output > 1 )THEN
547  WRITE(mpl_unit,'(A,5I8)') ' MPL_ALLREDUCE ',isendcount,icomm,ioper
548 ENDIF
549 IF(PRESENT(kerror)) THEN
550  kerror=ierror
551 ELSE
552  IF(ierror /= 0 ) CALL mpl_message(ierror,'MPL_ALLREDUCE',cdstring,ldabort=llabort)
553 ENDIF
554 
555 IF ( mpl_numproc > 1 ) &
556 psendbuf(:) = zrecvbuf(:)
557 
558 END SUBROUTINE mpl_allreduce_real4
559 
560 END MODULE mpl_allreduce_mod
561 
562 
static long size
Definition: bytes_io.c:262
subroutine, public mpl_message(KERROR, CDMESSAGE, CDSTRING, LDABORT)
integer, parameter jpim
Definition: parkind1.F90:13
integer, parameter jprd
Definition: parkind1.F90:39
subroutine mpl_allreduce_real8(PSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)
subroutine, public mpl_recvstats(ICOUNT, ITYPE)
integer(kind=jpim) mpl_numproc
logical lmplstats
Definition: yommplstats.F90:17
subroutine mpl_allreduce_int_scalar(KSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)
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)
integer(kind=jpim) mpl_errunit
subroutine mpl_allreduce_real4_scalar(PSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)
integer, parameter jprm
Definition: parkind1.F90:30
subroutine mpl_allreduce_real8_scalar(PSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)
subroutine mpl_allreduce_int8(KSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)
subroutine mpl_allreduce_real4(PSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)
integer(kind=jpim) mpl_rank
integer, parameter jpib
Definition: parkind1.F90:14
subroutine mpl_allreduce_int(KSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)
integer(kind=jpim) mpl_unit
integer(kind=jpim) mpl_output
subroutine mpl_allreduce_int8_scalar(KSENDBUF, CDOPER, LDREPROD, KCOMM, KERROR, CDSTRING)