SURFEX v8.1
General documentation of Surfex
mpl_scatterv_mod.F90
Go to the documentation of this file.
2 
3 !**** MPL_SCATTERV Scatter data from specific processor
4 
5 ! Purpose.
6 ! --------
7 ! Scatter data from specific processor
8 ! The data may be REAL*8,or INTEGER, one dimensional array
9 !
10 !** Interface.
11 ! ----------
12 ! CALL MPL_SCATTERV
13 
14 ! Input required arguments :
15 ! -------------------------
16 ! PRECVBUF - buffer containing message
17 ! (can be type REAL*4, REAL*8 or INTEGER)
18 ! PSENDBUF - buffer containing message
19 ! (required from kroot)
20 ! (can be type REAL*4, REAL*8 or INTEGER)
21 ! KSENDCOUNTS-number of elements to be sent to each process
22 ! (required from kroot processor)
23 
24 ! Input optional arguments :
25 ! -------------------------
26 ! KROOT - rank of sending processor (default 1)
27 ! KCOMM - Communicator number if different from MPI_COMM_WORLD
28 ! or from that established as the default
29 ! by an MPL communicator routine
30 ! KMP_TYPE - buffering type (see MPL_BUFFER_METHOD)
31 ! overrides value provided to MPL_BUFFER_METHOD
32 ! KSENDDISPL -displacements in PRECVBUF at which to place
33 ! the incoming data
34 ! CDSTRING - Character string for ABORT messages
35 ! used when KERROR is not provided
36 
37 ! Output required arguments :
38 ! -------------------------
39 ! none
40 
41 ! Output optional arguments :
42 ! -------------------------
43 ! KREQUEST - Communication request
44 ! required when buffering type is non-blocking
45 ! KERROR - return error code. If not supplied,
46 ! MPL_SCATTERV aborts when an error is detected.
47 ! Author.
48 ! -------
49 ! Y. Tremolet, M.Hamrud ECMWF
50 
51 ! Modifications.
52 ! --------------
53 ! Original: 02-03-13
54 ! M.Hamrud : 2014-10-22 : Add nonblocking option
55 ! F. Vana 05-Mar-2015 Support for single precision
56 
57 ! --- *NOT* THREAD SAFE YET ---
58 
59 ! ----------------------------------------------------------------
60 USE parkind1 ,ONLY : jprd, jpim, jprm
61 
62 USE mpl_mpif
64 USE mpl_stats_mod
65 USE yommplstats
68 
69 IMPLICIT NONE
70 PRIVATE
71 PUBLIC mpl_scatterv
72 
74 LOGICAL :: llabort=.true.
75 INTEGER(KIND=JPIM) :: ierror,idum
76 REAL(KIND=JPRD) :: zdum
77 REAL(KIND=JPRM) :: zdum_4
78 INTEGER(KIND=JPIM) :: zdum_int
79 
80 INTERFACE mpl_scatterv
82 END INTERFACE
83 
84 CONTAINS
85 
86 SUBROUTINE mpl_scatterv_preamb1(KCOMM,KROOT,KMP_TYPE,KREQUEST)
87 
88 
89 #ifdef USE_8_BYTE_WORDS
90  USE mpi4to8, ONLY : &
91  mpi_scatterv => mpi_scatterv8, mpi_comm_size => mpi_comm_size8
92 #endif
93 
94 
95 
96 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KCOMM
97 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KROOT
98 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KMP_TYPE
99 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KREQUEST
100 INTEGER(KIND=JPIM) :: ITID
101 itid = oml_my_thread()
102 
103 ierror = 0
104 
105 IF(mpl_numproc < 1) CALL mpl_message( &
106  & cdmessage='MPL_SCATTERV: MPL NOT INITIALISED ',ldabort=llabort)
107 
108 IF(PRESENT(kcomm)) THEN
109  icomm=kcomm
110 ELSE
111  icomm=mpl_comm_oml(itid)
112 ENDIF
113 
114 IF(PRESENT(kmp_type)) THEN
115  imp_type=kmp_type
116 ELSE
118 ENDIF
120  IF(.NOT.PRESENT(krequest)) CALL mpl_message(cdmessage='MPL_SCATTERV: KREQUEST MISSING',ldabort=llabort)
121 ENDIF
122 
123 IF(icomm == mpl_comm_oml(itid)) THEN
126 ELSE
127  CALL mpi_comm_size(icomm,ipl_numproc,ierror)
129 ENDIF
130 
131 IF(PRESENT(kroot)) THEN
132  iroot=kroot
133 ELSE
134  iroot=1
135 ENDIF
136 
137 END SUBROUTINE mpl_scatterv_preamb1
138 
139 SUBROUTINE mpl_scatterv_preamb2(KSENDCOUNTS,KISENDDISPL,KSENDDISPL,CDSTRING)
141 INTEGER(KIND=JPIM),INTENT(IN) :: KSENDCOUNTS(:)
142 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KSENDDISPL(:)
143 INTEGER(KIND=JPIM),INTENT(OUT) :: KISENDDISPL(:)
144 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
145 
146 
147 IF(SIZE(ksendcounts) < ipl_numproc) THEN
148  WRITE(mpl_errunit,*)'MPL_SCATTERV: ERROR KSENDCOUNTS DIMENSION=',&
149  & SIZE(ksendcounts)
150  CALL mpl_message(cdmessage=&
151  & 'MPL_SCATTERV: ERROR KSENDCOUNTS DIMENSION IS WRONG',ldabort=llabort)
152 ENDIF
153 IF(irecvcount /= ksendcounts(ipl_myrank)) THEN
154  WRITE(mpl_errunit,*)'MPL_SCATTERV: ERROR KSENDCOUNTS INCONSISTENCY ',&
155  & irecvcount,ksendcounts(ipl_myrank)
156  CALL mpl_message(cdmessage=&
157  & 'MPL_SCATTERV: ERROR IRECVCOUNT /= KSENDCOUNTS(MPL_RANK) ',ldabort=llabort)
158 ENDIF
159 
160 IF(PRESENT(ksenddispl)) THEN
161  kisenddispl(:) = ksenddispl(:)
162 ELSE
163  kisenddispl(:) = 0
164  DO ir=2, ipl_numproc
165  kisenddispl(ir) = kisenddispl(ir-1) + ksendcounts(ir-1)
166  ENDDO
167 ENDIF
168 DO ir=1, ipl_numproc
169  IF(kisenddispl(ir)+ksendcounts(ir) > isendbufsize) THEN
170  WRITE(mpl_errunit,'(A,4I10)')'MPL_SCATTERV:SEND BUFFER TOO SMALL ', &
171  & ir,kisenddispl(ir),ksendcounts(ir),isendbufsize
172  CALL mpl_message(cdmessage='MPL_SCATTERV',cdstring=cdstring,ldabort=llabort)
173  ENDIF
174 ENDDO
175 
176 END SUBROUTINE mpl_scatterv_preamb2
177 ! ------------------------------------------------------------------
178 SUBROUTINE mpl_scatterv_real8(PRECVBUF,KROOT,PSENDBUF,KSENDCOUNTS,KSENDDISPL,&
179  & KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
181 
182 #ifdef USE_8_BYTE_WORDS
183  USE mpi4to8, ONLY : &
184  mpi_scatterv => mpi_scatterv8
185 #endif
186 
187 
188 REAL(KIND=JPRD), INTENT(OUT) :: PRECVBUF(:)
189 INTEGER(KIND=JPIM), INTENT(IN) :: KROOT
190 REAL(KIND=JPRD), INTENT(IN),OPTIONAL :: PSENDBUF(:)
191 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KSENDCOUNTS(:), KSENDDISPL(:)
192 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
193 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KREQUEST
194 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
195 
196 INTEGER(KIND=JPIM) :: ISENDDISPL(mpl_numproc)
197 
198 CALL mpl_scatterv_preamb1(kcomm,kroot,kmp_type,krequest)
199 irecvcount=SIZE(precvbuf)
200 
201 IF(ipl_myrank == iroot) THEN
202  IF( .NOT. PRESENT(psendbuf)) CALL mpl_message(&
203  & cdmessage='MPL_SCATTERV:SENDBUF MISSING',cdstring=cdstring,&
204  & ldabort=llabort)
205  isendbufsize=SIZE(psendbuf)
206  CALL mpl_scatterv_preamb2(ksendcounts,isenddispl,ksenddispl,cdstring)
208  CALL mpi_scatterv(psendbuf,ksendcounts,isenddispl,int(mpi_real8), &
209  & precvbuf,irecvcount,int(mpi_real8),iroot-1,icomm,ierror)
211  CALL mpi_iscatterv(psendbuf,ksendcounts,isenddispl,int(mpi_real8), &
212  & precvbuf,irecvcount,int(mpi_real8),iroot-1,icomm,krequest,ierror)
213  ENDIF
214  IF(lmplstats) THEN
215  CALL mpl_sendstats(sum(ksendcounts),int(mpi_real8))
216  CALL mpl_recvstats(irecvcount,int(mpi_real8))
217  ENDIF
218 ELSE
220  CALL mpi_scatterv(zdum,1,1,int(mpi_real8), &
221  & precvbuf,irecvcount,int(mpi_real8),iroot-1,icomm,ierror)
223  CALL mpi_iscatterv(zdum,1,1,int(mpi_real8), &
224  & precvbuf,irecvcount,int(mpi_real8),iroot-1,icomm,krequest,ierror)
225  ENDIF
226  IF(lmplstats) THEN
227  CALL mpl_recvstats(irecvcount,int(mpi_real8))
228  ENDIF
229 ENDIF
230 
231 IF(PRESENT(kerror)) THEN
232  kerror=ierror
233 ELSE
234  IF (ierror/=0) CALL mpl_message(ierror,'MPL_SCATTERV',&
235  & cdstring,ldabort=llabort)
236 ENDIF
237 
238 END SUBROUTINE mpl_scatterv_real8
239 ! ------------------------------------------------------------------
240 SUBROUTINE mpl_scatterv_real4(PRECVBUF,KROOT,PSENDBUF,KSENDCOUNTS,KSENDDISPL,&
241  & KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
243 
244 #ifdef USE_8_BYTE_WORDS
245  USE mpi4to8, ONLY : &
246  mpi_scatterv => mpi_scatterv8
247 #endif
248 
249 
250 REAL(KIND=JPRM), INTENT(OUT) :: PRECVBUF(:)
251 INTEGER(KIND=JPIM), INTENT(IN) :: KROOT
252 REAL(KIND=JPRM), INTENT(IN),OPTIONAL :: PSENDBUF(:)
253 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KSENDCOUNTS(:), KSENDDISPL(:)
254 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
255 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KREQUEST
256 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
257 
258 INTEGER(KIND=JPIM) :: ISENDDISPL(mpl_numproc)
259 
260 CALL mpl_scatterv_preamb1(kcomm,kroot,kmp_type,krequest)
261 irecvcount=SIZE(precvbuf)
262 
263 IF(ipl_myrank == iroot) THEN
264  IF( .NOT. PRESENT(psendbuf)) CALL mpl_message(&
265  & cdmessage='MPL_SCATTERV:SENDBUF MISSING',cdstring=cdstring,&
266  & ldabort=llabort)
267  isendbufsize=SIZE(psendbuf)
268  CALL mpl_scatterv_preamb2(ksendcounts,isenddispl,ksenddispl,cdstring)
270  CALL mpi_scatterv(psendbuf,ksendcounts,isenddispl,int(mpi_real4), &
271  & precvbuf,irecvcount,int(mpi_real4),iroot-1,icomm,ierror)
273  CALL mpi_iscatterv(psendbuf,ksendcounts,isenddispl,int(mpi_real4), &
274  & precvbuf,irecvcount,int(mpi_real4),iroot-1,icomm,krequest,ierror)
275  ENDIF
276  IF(lmplstats) THEN
277  CALL mpl_sendstats(sum(ksendcounts),int(mpi_real4))
278  CALL mpl_recvstats(irecvcount,int(mpi_real4))
279  ENDIF
280 ELSE
282  CALL mpi_scatterv(zdum_4,1,1,int(mpi_real4), &
283  & precvbuf,irecvcount,int(mpi_real4),iroot-1,icomm,ierror)
285  CALL mpi_iscatterv(zdum_4,1,1,int(mpi_real4), &
286  & precvbuf,irecvcount,int(mpi_real4),iroot-1,icomm,krequest,ierror)
287  ENDIF
288  IF(lmplstats) THEN
289  CALL mpl_recvstats(irecvcount,int(mpi_real4))
290  ENDIF
291 ENDIF
292 
293 IF(PRESENT(kerror)) THEN
294  kerror=ierror
295 ELSE
296  IF (ierror/=0) CALL mpl_message(ierror,'MPL_SCATTERV',&
297  & cdstring,ldabort=llabort)
298 ENDIF
299 
300 END SUBROUTINE mpl_scatterv_real4
301 
302 
303 SUBROUTINE mpl_scatterv_integer(KRECVBUF,KROOT,KSENDBUF,KSENDCOUNTS,&
304  & KSENDDISPL,KMP_TYPE,KCOMM,KERROR,KREQUEST,CDSTRING)
306 
307 #ifdef USE_8_BYTE_WORDS
308  USE mpi4to8, ONLY : &
309  mpi_scatterv => mpi_scatterv8
310 #endif
311 
312 
313 INTEGER(KIND=JPIM), INTENT(OUT) :: KRECVBUF(:)
314 INTEGER(KIND=JPIM), INTENT(IN) :: KROOT
315 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KSENDBUF(:)
316 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KSENDCOUNTS(:), KSENDDISPL(:)
317 INTEGER(KIND=JPIM), INTENT(IN),OPTIONAL :: KCOMM,KMP_TYPE
318 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KREQUEST
319 CHARACTER*(*),INTENT(IN),OPTIONAL :: CDSTRING
320 
321 INTEGER(KIND=JPIM) :: ISENDDISPL(mpl_numproc)
322 
323 CALL mpl_scatterv_preamb1(kcomm,kroot,kmp_type,krequest)
324 irecvcount=SIZE(krecvbuf)
325 
326 IF(ipl_myrank == iroot) THEN
327  IF( .NOT. PRESENT(ksendbuf)) CALL mpl_message(&
328  & cdmessage='MPL_SCATTERV:SENDBUF MISSING',cdstring=cdstring,&
329  & ldabort=llabort)
330  isendbufsize=SIZE(ksendbuf)
331  CALL mpl_scatterv_preamb2(ksendcounts,isenddispl,ksenddispl,&
332  & cdstring)
334  CALL mpi_scatterv(ksendbuf,ksendcounts,isenddispl,int(mpi_integer), &
335  & krecvbuf,irecvcount,int(mpi_integer),iroot-1,icomm,ierror)
337  CALL mpi_iscatterv(ksendbuf,ksendcounts,isenddispl,int(mpi_integer), &
338  & krecvbuf,irecvcount,int(mpi_integer),iroot-1,icomm,krequest,ierror)
339  ENDIF
340  IF(lmplstats) THEN
341  CALL mpl_sendstats(sum(ksendcounts),int(mpi_integer))
342  CALL mpl_recvstats(irecvcount,int(mpi_integer))
343  ENDIF
344 ELSE
346  CALL mpi_scatterv(zdum_int,1,1,int(mpi_integer), &
347  & krecvbuf,irecvcount,int(mpi_integer),iroot-1,icomm,ierror)
349  CALL mpi_iscatterv(zdum_int,1,1,int(mpi_integer), &
350  & krecvbuf,irecvcount,int(mpi_integer),iroot-1,icomm,krequest,ierror)
351  ENDIF
352  IF(lmplstats) THEN
353  CALL mpl_recvstats(irecvcount,int(mpi_integer))
354  ENDIF
355 ENDIF
356 
357 IF(PRESENT(kerror)) THEN
358  kerror=ierror
359 ELSE
360  IF (ierror/=0) CALL mpl_message(ierror,'MPL_SCATTERV',&
361  & cdstring,ldabort=llabort)
362 ENDIF
363 
364 END SUBROUTINE mpl_scatterv_integer
365 ! ------------------------------------------------------------------
366 
367 END MODULE mpl_scatterv_mod
integer(kind=jpim) idum
subroutine, public mpl_message(KERROR, CDMESSAGE, CDSTRING, LDABORT)
integer(kind=jpim) ir
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) isendbufsize
integer(kind=jpim) mpl_numproc
integer(kind=jpim) zdum_int
logical lmplstats
Definition: yommplstats.F90:17
subroutine mpl_scatterv_preamb2(KSENDCOUNTS, KISENDDISPL, KSENDDISPL, CDSTRING)
integer(kind=jpim), parameter jp_non_blocking_standard
integer(kind=jpim), dimension(:), allocatable mpl_comm_oml
subroutine mpl_scatterv_real4(PRECVBUF, KROOT, PSENDBUF, KSENDCOUNTS, KSENDDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
integer(kind=jpim), parameter jp_blocking_standard
real(kind=jprm) zdum_4
subroutine, public mpl_sendstats(ICOUNT, ITYPE)
integer(kind=jpim) ierror
integer(kind=jpim) ipl_myrank
integer(kind=jpim), parameter jp_non_blocking_buffered
integer(kind=jpim) mpl_errunit
integer(kind=jpim) icomm
real(kind=jprd) zdum
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) function, public mpl_myrank(KCOMM)
subroutine mpl_scatterv_preamb1(KCOMM, KROOT, KMP_TYPE, KREQUEST)
integer(kind=jpim) mpl_rank
integer(kind=jpim) mpl_method
subroutine mpl_scatterv_integer(KRECVBUF, KROOT, KSENDBUF, KSENDCOUNTS, KSENDDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)
integer(kind=jpim) iroot
integer(kind=jpim) ipl_numproc
integer(kind=jpim) imp_type
integer(kind=jpim) irecvcount
subroutine mpl_scatterv_real8(PRECVBUF, KROOT, PSENDBUF, KSENDCOUNTS, KSENDDISPL, KMP_TYPE, KCOMM, KERROR, KREQUEST, CDSTRING)