SURFEX v8.1
General documentation of Surfex
mpl_arg_mod.F90
Go to the documentation of this file.
1 MODULE mpl_arg_mod
2 
3 !**** MPL_GETARG : A substitute for GETARG for MPL applications
4 ! MPL_IARGC : A substitute for function IARGC for MPL applications
5 
6 ! Purpose.
7 ! --------
8 ! MPL-task#1 calls getarg until iargc() arguments read
9 ! or until the argument is a terminating argument
10 ! Then arguments are passed on to other processors
11 ! If MPL has not been initialized, it will be done now.
12 
13 !** Interface.
14 ! ----------
15 ! CALL MPL_GETARG(KARG, CDARG)
16 
17 ! Input required arguments :
18 ! -------------------------
19 ! KARG - The argument number requested (INTEGER(4))
20 ! Range : [ 0 .. MPL_IARGC() ]
21 
22 ! Output required arguments :
23 ! ---------------------------
24 ! CDARG - Return argument value (CHARACTER(LEN=*))
25 !
26 !** Interface.
27 ! ----------
28 ! INUM_ARGS = MPL_IARGC()
29 !
30 ! where INUM_ARGS is INTEGER(4)
31 
32 ! Author.
33 ! -------
34 ! S.Saarinen, G.Mozdzynski ECMWF
35 
36 ! Modifications.
37 ! --------------
38 ! Original: 2006-03-15
39 
40 USE parkind1 ,ONLY : jpim
41 USE mpl_mpif
43 
44 
45 #ifdef NAG
46 USE f90_unix_env, ONLY: getarg, iargc
47 #endif
48 
49 IMPLICIT NONE
50 
51 PRIVATE
52 
53 CHARACTER(LEN=10), SAVE :: cl_terminate = '-^' ! terminating argument
54 
55 INTEGER(KIND=JPIM), PARAMETER :: jp_arglen = 1024
56 CHARACTER(LEN=JP_ARGLEN), ALLOCATABLE, SAVE :: cl_args(:)
57 INTEGER(KIND=JPIM), SAVE :: n_args = -1
58 
59 PUBLIC :: mpl_getarg
60 PUBLIC :: mpl_iargc
63 
64 CONTAINS
65 
66 SUBROUTINE mpl_arg_set_cl_terminate(CDTERM)
67 CHARACTER(LEN=*), INTENT(IN) :: CDTERM
68 cl_terminate = cdterm
69 END SUBROUTINE mpl_arg_set_cl_terminate
70 
71 SUBROUTINE mpl_arg_get_cl_terminate(CDTERM)
72 CHARACTER(LEN=*), INTENT(OUT) :: CDTERM
73 cdterm = cl_terminate
74 END SUBROUTINE mpl_arg_get_cl_terminate
75 
76 SUBROUTINE init_args()
77 
78 #ifdef USE_8_BYTE_WORDS
79  USE mpi4to8, ONLY : &
80  mpi_initialized => mpi_initialized8, mpi_comm_size => mpi_comm_size8, &
81  mpi_comm_rank => mpi_comm_rank8, mpi_bcast => mpi_bcast8, &
82  mpi_init => mpi_init8
83 #endif
84 
85 INTEGER(KIND=JPIM) :: IARGS
86 INTEGER(KIND=JPIM) :: IERROR, IROOT, ICOUNT
87 INTEGER(KIND=JPIM) :: IRANK, INUMPROC, IRET, J
88 #ifndef NAG
89 INTEGER(KIND=JPIM) :: IARGC
90 #endif
91 INTEGER(KIND=JPIM) :: IARGC_C
92 CHARACTER(LEN=LEN(CL_TERMINATE)) :: ENV_CL_TERMINATE
93 CHARACTER(LEN=JP_ARGLEN) :: CLARG0
94 LOGICAL LLCARGS
95 INTEGER LLINIT
96 INTEGER(KIND=JPIM) :: ICOMM
97 
98 IF (n_args == -1) THEN
99  IF (mpl_numproc == -1) THEN
100  ! This is complicated, but I hope it works:
101  ! MPI has not yet been initialized, when this routines was called.
102  ! Initialize MPI, but NOT via MPL_INIT to avoid recursion in MPL_IARGC()
103  ! However, must pretend that MPL_INIT has actually initialized it, but
104  ! MPL_NUMPROC will not be set
105  CALL mpi_initialized(llinit,iret)
106  IF (llinit == 0) THEN
107  CALL mpi_init(ierror)
108  linitmpi_via_mpl = .true.
109  CALL ec_mpi_atexit() ! ifsaux/support/endian.c: to make sure MPI_FINALIZE gets called
110  ENDIF
111  ENDIF
112 
113  ! If LMPLUSERCOMM is not set use MPI_COMM_WORLD
114  IF (lmplusercomm) THEN
115  icomm = mplusercomm
116  ELSE
117  icomm = mpi_comm_world
118  ENDIF
119 
120  CALL mpi_comm_size(icomm,inumproc,ierror)
121  CALL mpi_comm_rank(icomm,irank,ierror)
122  irank=irank+1
123 
124  IF (irank == 1 .OR. inumproc == 1) THEN
125  CALL get_environment_variable('MPL_CL_TERMINATE',env_cl_terminate)
126  IF (env_cl_terminate /= ' ') cl_terminate = env_cl_terminate
127  iargs = iargc()
128  llcargs = (iargs < 0) ! Should be true for non-F90 main programs
129  IF (llcargs) THEN
130  iargs = iargc_c()
131  llcargs = (iargs >= 0)
132  CALL getarg_c(0,clarg0) ! The executable name (see ifsaux/support/cargs.c)
133  ELSE
134  CALL putarg_info(iargs, trim(cl_terminate)) ! (see ifsaux/support/cargs.c)
135  CALL getarg(0,clarg0) ! The executable name (normal F90 way)
136  CALL putarg_c(0,trim(clarg0)) ! (see ifsaux/support/cargs.c)
137  ENDIF
138  IF (iargs < 0) iargs = 0
139  ALLOCATE(cl_args(0:iargs))
140  n_args = 0
141  cl_args(0) = clarg0
142  DO j=1,iargs ! Other args (repeat until end of loop or terminating argument found)
143  IF (llcargs) THEN
144  CALL getarg_c(j,cl_args(j))
145  ELSE
146  CALL getarg(j,cl_args(j))
147  CALL putarg_c(j,trim(cl_args(j)))
148  ENDIF
149  IF (cl_args(j) == cl_terminate) EXIT
150  n_args = n_args + 1
151  ENDDO
152  ENDIF
153 
154  IF (inumproc > 1) THEN
155  iroot = 0
156  iargs = 0
157  IF (irank == 1) iargs = n_args
158  ! The following broadcast does not use "mailbox" nor attached buffer, both potentially yet to be allocated
159  CALL mpi_bcast(iargs,1,mpi_integer,iroot,icomm,ierror)
160  icount = jp_arglen
161  IF (irank > 1) ALLOCATE(cl_args(0:iargs))
162  IF (irank > 1) CALL putarg_info(iargs, trim(cl_terminate))
163  DO j=0,iargs
164  ! The following broadcast does not use "mailbox" nor attached buffer, both potentially yet to be allocated
165  CALL mpi_bcast(cl_args(j),icount,mpi_byte,iroot,icomm,ierror)
166  IF (irank > 1) CALL putarg_c(j,trim(cl_args(j)))
167  ENDDO
168  IF (irank > 1) n_args = iargs
169  ENDIF
170 ENDIF
171 END SUBROUTINE init_args
172 
173 SUBROUTINE mpl_getarg(KARG, CDARG)
174 INTEGER(KIND=JPIM), INTENT(IN) :: KARG
175 CHARACTER(LEN=*), INTENT(OUT) :: CDARG
176 #ifndef NAG
177 INTEGER(KIND=JPIM) :: IARGC
178 #endif
179 IF (n_args == -1) CALL init_args()
180 IF (karg >= 0 .AND. karg <= n_args) THEN
181  cdarg = cl_args(karg)
182 ELSE
183  cdarg = ' '
184 ENDIF
185 END SUBROUTINE mpl_getarg
186 
187 FUNCTION mpl_iargc() RESULT(IRET)
188 INTEGER(KIND=JPIM) :: IRET
189 IF (n_args == -1) CALL init_args()
190 iret = n_args
191 END FUNCTION mpl_iargc
192 
193 END MODULE mpl_arg_mod
integer(kind=jpim), parameter jp_arglen
Definition: mpl_arg_mod.F90:55
integer(kind=jpim) mplusercomm
integer, parameter jpim
Definition: parkind1.F90:13
integer(kind=jpim) mpl_numproc
void putarg_c(const int *argno, const char *arg, int arg_len)
Definition: cargs.c:215
void getarg_c(const int *argno, char *arg, const int arg_len)
Definition: cargs.c:190
subroutine, public mpl_arg_get_cl_terminate(CDTERM)
Definition: mpl_arg_mod.F90:72
void ec_mpi_atexit(void)
Definition: endian.c:71
integer(kind=jpim) function, public mpl_iargc()
subroutine init_args()
Definition: mpl_arg_mod.F90:77
void putarg_info(const int *argc, const char *cterm, int cterm_len)
Definition: cargs.c:251
subroutine getarg(IARG, CLARG)
Definition: get_opt.F:91
integer(kind=jpim), save n_args
Definition: mpl_arg_mod.F90:57
character(len=10), save cl_terminate
Definition: mpl_arg_mod.F90:53
subroutine, public mpl_arg_set_cl_terminate(CDTERM)
Definition: mpl_arg_mod.F90:67
character(len=jp_arglen), dimension(:), allocatable, save cl_args
Definition: mpl_arg_mod.F90:56
subroutine, public mpl_getarg(KARG, CDARG)