SURFEX v8.1
General documentation of Surfex
mpl_init_mod.F90
Go to the documentation of this file.
2 
3 !**** MPL_INIT - Initialises the Message passing environment
4 
5 ! Purpose.
6 ! --------
7 ! Must be called before any other MPL routine.
8 
9 !** Interface.
10 ! ----------
11 ! CALL MPL_INIT
12 
13 ! Input required arguments :
14 ! -------------------------
15 ! none
16 
17 ! Input optional arguments :
18 ! -------------------------
19 ! KOUTPUT - Level of printing for MPL routines
20 ! =0: none
21 ! =1: intermediate (default)
22 ! =2: full trace
23 ! KUNIT - Fortran Unit to receive printed trace
24 ! LDINFO - = .TRUE. : Print informative msgs from MPL_INIT (default)
25 ! = .FALSE. : Do not print
26 
27 ! Output required arguments :
28 ! -------------------------
29 ! none
30 
31 ! Output optional arguments :
32 ! -------------------------
33 ! KERROR - return error code. If not supplied,
34 ! MPL_INIT aborts when an error is detected.
35 ! KPROCS - Number of processes which have been initialised
36 ! in the MPI_COMM_WORLD communicator
37 ! Author.
38 ! -------
39 ! D.Dent, M.Hamrud ECMWF
40 
41 ! Modifications.
42 ! --------------
43 ! Original: 2000-09-01
44 ! R. El Khatib 14-May-2007 Do not propagate environment if NECSX
45 ! S. Saarinen 04-Oct-2009 Reduced output & redefined MPL_COMM_OML(1)
46 ! P. Marguinaud 01-Jan-2011 Add LDENV argument
47 ! R. El Khatib 24-May-2011 Make MPI2 the default expectation.
48 ! P. Towers 3-Jul-2014 Add call to ec_cray_meminfo
49 ! ------------------------------------------------------------------
50 
51 USE parkind1 ,ONLY : jpim ,jprb
52 USE oml_mod, ONLY : oml_init, oml_max_threads
53 USE mpl_mpif
59 USE mpl_arg_mod
60 
61 IMPLICIT NONE
62 
63 PUBLIC mpl_init
64 
65 PRIVATE
66 
67 CONTAINS
68 
69 SUBROUTINE mpl_init(KOUTPUT,KUNIT,KERROR,KPROCS,LDINFO,LDENV)
70 
71 #ifdef USE_8_BYTE_WORDS
72  USE mpi4to8, ONLY : &
73  mpi_initialized => mpi_initialized8, mpi_init => mpi_init8, &
74  mpi_comm_size => mpi_comm_size8, mpi_comm_rank => mpi_comm_rank8, &
75  mpi_bcast => mpi_bcast8
76 #endif
77 
78 
79 
80 INTEGER(KIND=JPIM),INTENT(IN),OPTIONAL :: KOUTPUT,KUNIT
81 INTEGER(KIND=JPIM),INTENT(OUT),OPTIONAL :: KERROR,KPROCS
82 LOGICAL,INTENT(IN),OPTIONAL :: LDINFO,LDENV
83 INTEGER(KIND=JPIM) :: IERROR,IP,ICOMM,IRANK,JNODE,JROC,ISTA
84 INTEGER(KIND=JPIM) :: IMAX_THREADS, IRET, IROOT, INUM(2), ICOUNT
85 INTEGER(KIND=JPIM) :: IREQUIRED,IPROVIDED
86 INTEGER(KIND=JPIM) :: IWORLD_RANK, IWORLD_SIZE
87 LOGICAL :: LLABORT=.true., llinfo
88 INTEGER :: LLINIT
89 LOGICAL :: LLENV
90 CHARACTER(LEN=12) :: CL_MBX_SIZE
91 CHARACTER(LEN=12) :: CL_ARCH
92 CHARACTER(LEN=12) :: CL_TASKSPERNODE
93 CHARACTER(LEN=1024) :: CLENV
94 CHARACTER(LEN=20) :: CL_METHOD,CL_HOST
95 
96 IF(PRESENT(koutput)) THEN
97  mpl_output=max(0,koutput)
98 ELSE
99  mpl_output=1
100 ENDIF
101 
102 IF(PRESENT(kunit)) THEN
103  mpl_unit=max(0,kunit)
104 ELSE
105  mpl_unit=6
106 ENDIF
107 
108 IF(PRESENT(ldinfo)) THEN
109  llinfo = ldinfo
110 ELSE
111  llinfo = .true.
112 ENDIF
113 
114 IF(PRESENT(ldenv)) THEN
115  llenv = ldenv
116 ELSE
117  llenv = .true.
118 ENDIF
119 
120 ! If LMPLUSERCOMM is not set use MPI_COMM_WORLD
121 IF(lmplusercomm) THEN
123 ELSE
124  mpl_comm = mpi_comm_world
125 ENDIF
126 
127 IF(mpl_numproc /= -1) THEN
128 !! We do not want this extra message
129 !! CALL MPL_MESSAGE(CDMESSAGE=' MPL_INIT CALLED MULTIPLE TIMES ')
130  IF(PRESENT(kerror)) THEN
131  kerror=0
132  ENDIF
133  IF(PRESENT(kprocs)) THEN
134  kprocs=mpl_numproc
135  ENDIF
136  RETURN
137 ENDIF
138 
139 CALL mpi_initialized(llinit, iret)
140 
141 IF (llinit == 0) THEN
142 
143  CALL get_environment_variable('ARCH',cl_arch)
144 
145 #ifndef OPS_COMPILE
146 #ifdef RS6K
147  IF(cl_arch(1:10)=='ibm_power6')THEN
148 ! write(0,*)'POWER6: CALLING EC_BIND BEFORE MPI_INIT'
149  CALL ec_bind()
150  ENDIF
151 #endif
152 #endif
153 
154 #ifndef MPI1
155  irequired = mpi_thread_multiple
156  iprovided = mpi_thread_single
157  CALL mpi_init_thread(irequired,iprovided,ierror)
158  lthsafempi = (iprovided >= irequired)
159 #else
160  CALL mpi_init(ierror)
161  lthsafempi = .false.
162 #endif
163 
164 #ifndef OPS_COMPILE
165 #ifdef RS6K
166  IF(cl_arch(1:10)=='ibm_power4')THEN
167 ! write(0,*)'POWER5: CALLING EC_BIND AFTER MPI_INIT'
168  CALL ec_bind()
169  ENDIF
170 #endif
171 #endif
172 
173  linitmpi_via_mpl = .true.
174 ! CALL ec_mpi_atexit() ! ifsaux/support/endian.c: to make sure MPI_FINALIZE gets called
175 
176 ELSE
177  ierror = 0
178 ENDIF
179 
180 IF(PRESENT(kerror)) THEN
181  kerror=ierror
182 ELSE
183  IF(ierror /= 0) THEN
184  CALL mpl_message(ierror,cdmessage=' MPL_INIT ERROR ',ldabort=llabort)
185  ENDIF
186 ENDIF
187 
188 CALL mpi_comm_size(mpl_comm,mpl_numproc,ierror)
189 
190 IF(PRESENT(kprocs)) THEN
191  kprocs=mpl_numproc
192 ENDIF
193 
194 ALLOCATE (mpl_ids(mpl_numproc))
195 DO ip=1,mpl_numproc
196  mpl_ids(ip)=ip
197 ENDDO
198 
199 CALL mpi_comm_rank(mpl_comm, irank, ierror)
200 mpl_rank=irank+1
201 
202 llinfo = llinfo .AND. (mpl_rank <= 1)
203 
204 IF (llinfo) THEN
205  IF(lmplusercomm) THEN
206  WRITE(mpl_unit,'(A)')'MPL_INIT : LMPLUSERCOMM used'
207  WRITE(mpl_unit,'(A,I8)')'Communicator : ',mpl_comm
208  ELSE
209  WRITE(mpl_unit,'(A)')'MPL_INIT : LMPLUSERCOMM not used'
210  WRITE(mpl_unit,'(A,I8)')'Communicator : ',mpl_comm
211  ENDIF
212 ENDIF
213 
214 #ifndef NECSX
215 
216 !-- Propagate environment variables & argument lists
217 ! Here we have to be careful and use MPI_BCAST directly (not MPL_BROADCAST) since
218 ! 1) MPL_BUFFER_METHOD has not been called
219 ! 2) MPL_COMM_OML has not been initialized since it is possible that only the
220 ! master proc knows the # of threads (i.e. OMP_NUM_THREADS may be set only for master)
221 
222 ! Do not propagate on nec machine because the environment variables could be mpi-task-specific.
223 
224 IF (mpl_numproc > 1 .AND. llenv) THEN
225  iroot = 0
226  !-- Progate environment variables
227  inum(1) = 0 ! The number of environment variables
228  inum(2) = 0 ! Do not (=0) or do (=1) overwrite if particular environment variable already exists (0 = default)
229  IF (mpl_rank == 1) THEN ! Master proc inquires
230  CALL ec_numenv(inum(1)) ! ../support/env.c
231  CALL ec_overwrite_env(inum(2)) ! ../support/env.c
232  ENDIF
233  ! The following broadcast does not use "mailbox" nor attached buffer, both potentially yet to be allocated
234  CALL mpi_bcast(inum(1),2,int(mpi_integer),iroot,mpl_comm,ierror)
235  icount = len(clenv)
236  DO ip=1,inum(1)
237  IF (mpl_rank == 1) CALL ec_strenv(ip,clenv)
238  ! The following broadcast does not use "mailbox" nor attached buffer, both potentially yet to be allocated
239  CALL mpi_bcast(clenv,icount,int(mpi_byte),iroot,mpl_comm,ierror)
240  IF (mpl_rank > 1) THEN
241  IF (inum(2) == 1) THEN
242  CALL ec_putenv(clenv) ! ../support/env.c ; Unconditionally overwrite, even if already exists
243  ELSE
244  CALL ec_putenv_nooverwrite(clenv) ! ../support/env.c ; Do not overwrite, if exists
245  ENDIF
246  ENDIF
247  ENDDO
248  !-- Redo some env. variables (see ../utilities/fnecsx.c)
249  CALL ec_envredo()
250  !-- Propagate argument list (all under the bonnet using MPL_ARG_MOD-module)
251  inum = mpl_iargc()
252 ENDIF
253 
254 #endif
255 
256 CALL oml_init()
257 imax_threads = oml_max_threads()
258 ALLOCATE(mpl_comm_oml(imax_threads))
259 
260 IF (lmplusercomm) THEN
262  ista = 2
263 ELSE
264  ista = 1
265 ENDIF
266 
267 DO ip=ista,imax_threads
269 ENDDO
270 mpl_comm = mpl_comm_oml(1) ! i.e. not necessary MPI_COMM_WORLD anymore
271 
272 #ifdef VPP
274 mpl_mbx_size=4000000
275 cl_mbx_size=' '
276 CALL get_environment_variable('VPP_MBX_SIZE',cl_mbx_size)
277 IF(cl_mbx_size == ' ') THEN
278  CALL get_environment_variable('MPL_MBX_SIZE',cl_mbx_size)
279 ENDIF
280 IF(cl_mbx_size /= ' ') THEN
281  READ(cl_mbx_size,*) mpl_mbx_size
282 ENDIF
283 IF (llinfo) WRITE(mpl_unit,'(A)')'MPL_INIT : MPL_METHOD=JP_BLOCKING_STANDARD'
284 IF (llinfo) WRITE(mpl_unit,'(A,I12)')'MPL_INIT : MAILBOX SIZE=',mpl_mbx_size
285 lusehlmpi = .false.
286 
287 !#elif defined (LINUX)
288 !MPL_METHOD=JP_BLOCKING_STANDARD
289 !MPL_MBX_SIZE=4000000
290 !CL_MBX_SIZE=' '
291 !CALL GET_ENVIRONMENT_VARIABLE('VPP_MBX_SIZE',CL_MBX_SIZE)
292 !IF(CL_MBX_SIZE == ' ') THEN
293 ! CALL GET_ENVIRONMENT_VARIABLE('MPL_MBX_SIZE',CL_MBX_SIZE)
294 !ENDIF
295 !IF(CL_MBX_SIZE /= ' ') THEN
296 ! READ(CL_MBX_SIZE,*) MPL_MBX_SIZE
297 !ENDIF
298 !IF (LLINFO) WRITE(MPL_UNIT,'(A)')'MPL_INIT : MPL_METHOD=JP_BLOCKING_STANDARD'
299 !IF (LLINFO) WRITE(MPL_UNIT,'(A,I12)')'MPL_INIT : MAILBOX SIZE=',MPL_MBX_SIZE
300 !LUSEHLMPI = .FALSE.
301 
302 #else
303 cl_method=' '
304 CALL get_environment_variable('MPL_METHOD',cl_method)
305 IF (cl_method == 'JP_BLOCKING_STANDARD' ) THEN
307 ELSE
309 ENDIF
310 mpl_mbx_size=1000000
311 cl_mbx_size=' '
312 CALL get_environment_variable('MPL_MBX_SIZE',cl_mbx_size)
313 IF (cl_mbx_size /= ' ') THEN
314  READ(cl_mbx_size,*) mpl_mbx_size
315 ENDIF
316 IF (cl_method == 'JP_BLOCKING_STANDARD' ) THEN
317  IF (llinfo) WRITE(mpl_unit,'(A)')'MPL_INIT : MPL_METHOD=JP_BLOCKING_STANDARD'
318 ELSE
319  IF (llinfo) WRITE(mpl_unit,'(A)')'MPL_INIT : MPL_METHOD=JP_BLOCKING_BUFFERED'
320 ENDIF
321 !IF (LLINFO) WRITE(MPL_UNIT,'(A,I12)')'MPL_INIT : MAILBOX SIZE=',MPL_MBX_SIZE
322 
323 CALL mpl_buffer_method(kmp_type=mpl_method,kmbx_size=mpl_mbx_size,ldinfo=llinfo)
324 lusehlmpi = .true.
325 #endif
326 
327 #ifdef LINUX
328 CALL mpi_comm_rank (mpi_comm_world, iworld_rank, ierror)
329 CALL mpi_comm_size (mpi_comm_world, iworld_size, ierror)
330 CALL linux_bind (iworld_rank, iworld_size)
331 #endif
332 
333 !!!! If you are not at ECMWF this may need changing!!!!
334 CALL get_environment_variable('EC_TASKS_PER_NODE',cl_taskspernode)
335 IF (cl_taskspernode(1:1) == ' ' ) THEN
336  CALL get_environment_variable('HOST',cl_host)
337  IF (cl_host(1:2) == 'c1') THEN
339  ELSEIF(cl_host(1:3) == 'hpc') THEN
341  ELSEIF(cl_host(1:2) == 'cc') THEN
343  ELSE
345  IF(llinfo) WRITE(mpl_unit,'(A)')'MPL_INIT CAUTION: MPL_NCPU_PER_NODE=1'
346  ENDIF
347 ELSE
348  READ(cl_taskspernode,*) mpl_ncpu_per_node
349 ENDIF
350 mpl_max_task_per_node=max(1, mpl_ncpu_per_node/imax_threads)
353 ALLOCATE(mpl_task_per_node(mpl_nnodes))
354 ALLOCATE(mpl_node(mpl_numproc))
356 mpl_node_tasks(:,:)=-99
357 icount=0
358 DO jnode=1,mpl_nnodes
359  DO jroc=1,mpl_max_task_per_node
360  icount=icount+1
361  IF (icount<=mpl_numproc) THEN
362  mpl_node(icount)=jnode
363  mpl_task_per_node(jnode) = jroc
364  mpl_node_tasks(jnode,jroc) = icount
365  ENDIF
366  ENDDO
367 ENDDO
369 !WRITE(MPL_UNIT,*) 'MPL_INIT : NCPU_PER_NODE,MPL_MAX_TASK_PER_NODE,MPL_NNODES,MPL_MYNODE ',&
370 ! & MPL_NCPU_PER_NODE,MPL_MAX_TASK_PER_NODE,MPL_NNODES,MPL_MYNODE
371 !WRITE(MPL_UNIT,*) 'MPL_INIT : MPL_NODE_TASKS(MPL_MYNODE,1:MPL_TASK_PER_NODE(MPL_MYNODE)) ', &
372 ! & MPL_NODE_TASKS(MPL_MYNODE,1:MPL_TASK_PER_NODE(MPL_MYNODE))
373 
374 ALLOCATE(mpl_opponent(mpl_numproc+1))
376 
377 #ifdef _CRAYFTN
378  CALL ec_cray_meminfo(-1,"mpl_init",mpl_comm)
379 #endif
380 
381 RETURN
382 END SUBROUTINE mpl_init
383 
384 END MODULE mpl_init_mod
void ec_strenv(const int *i, char *value, const int valuelen)
Definition: env.c:87
subroutine, public mpl_message(KERROR, CDMESSAGE, CDSTRING, LDABORT)
void ec_putenv(const char *s, int slen)
Definition: env.c:157
integer(kind=jpim) mplusercomm
integer(kind=jpim), parameter jp_blocking_buffered
integer, parameter jpim
Definition: parkind1.F90:13
integer(kind=jpim) mpl_mynode
integer(kind=jpim) mpl_numproc
subroutine, public mpl_buffer_method(KMP_TYPE, KMBX_SIZE, KERROR, KPROCIDS, LDINFO)
integer(kind=jpim), dimension(:,:), allocatable mpl_node_tasks
subroutine, public mpl_locomm_create(N, KCOMM)
integer(kind=jpim), dimension(:), allocatable mpl_node
integer(kind=jpim), dimension(:), allocatable mpl_task_per_node
integer(kind=jpim) mpl_nnodes
integer(kind=jpim), dimension(:), allocatable mpl_comm_oml
subroutine ec_cray_meminfo(IU, IDSTRING, KCOMM)
integer(kind=jpim), parameter jp_blocking_standard
integer(kind=jpim) mpl_max_task_per_node
integer(kind=jpim) mpl_ncpu_per_node
integer, parameter jprb
Definition: parkind1.F90:32
subroutine, public mpl_init(KOUTPUT, KUNIT, KERROR, KPROCS, LDINFO, LDENV)
subroutine, public mpl_tour_table(KOPPONENT, KEVEN)
void ec_overwrite_env(int *do_overwrite)
Definition: env.c:60
integer(kind=jpim) function, public mpl_iargc()
integer(kind=jpim) mpl_comm
integer(kind=jpim), dimension(:), allocatable mpl_opponent
integer(kind=jpim) mpl_rank
void ec_envredo()
Definition: fnecsx.c:388
integer(kind=jpim) mpl_mbx_size
integer(kind=jpim) mpl_method
integer(kind=jpim) function, public oml_max_threads()
Definition: oml_mod.F90:256
void ec_numenv(int *n)
Definition: env.c:38
integer(kind=jpim), dimension(:), allocatable mpl_ids
integer(kind=jpim) mpl_unit
void ec_putenv_nooverwrite(const char *s, int slen)
Definition: env.c:205
subroutine, public oml_init()
Definition: oml_mod.F90:111
integer(kind=jpim) mpl_output