TABLE OF CONTENTS
- ABINIT/m_exit
- m_exit/disable_timelimit
- m_exit/enable_timelimit_in
- m_exit/exit_check
- m_exit/exit_init
- m_exit/get_start_time
- m_exit/get_timelimit
- m_exit/get_timelimit_string
- m_exit/have_timelimit_in
ABINIT/m_exit [ Modules ]
NAME
m_exit
FUNCTION
COPYRIGHT
Copyright (C) 2008-2024 ABINIT group (MG, DCA, XG, GMR) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
SOURCE
15 #if defined HAVE_CONFIG_H 16 #include "config.h" 17 #endif 18 19 #include "abi_common.h" 20 21 MODULE m_exit 22 23 use defs_basis 24 use m_xmpi 25 use m_abicore 26 use m_errors 27 28 use m_time, only : abi_wtime, sec2str, timein 29 use m_fstrings, only : inupper 30 use m_io_tools, only : open_file 31 32 implicit none 33 34 private
m_exit/disable_timelimit [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
disable_timelimit
FUNCTION
Disable the time limit handler. This function should be called by a driver routine that is not able to handle time limit events and wants to prevent its children from installing their handlers.
SOURCE
105 subroutine disable_timelimit() 106 107 !Local variables------------------------------- 108 !scalars 109 character(len=500) :: msg 110 111 ! ************************************************************************* 112 113 WTIME_LIMIT = -one 114 115 if (TIMELIMIT_INABIFUNC /= "__None__") then 116 msg = "Timelimit is already activated in function: "//trim(TIMELIMIT_INABIFUNC) 117 ABI_WARNING(msg) 118 !ABI_ERROR(msg) 119 end if 120 121 end subroutine disable_timelimit
m_exit/enable_timelimit_in [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
enable_timelimit_in
FUNCTION
Eable time limit handler in the given function if not already done in one of the callers. Return the name of procedure that is handling the time limit. Example: ! enable time limit handler if not done in callers. if (enable_timelimit_in(FUNC_NAME) == FUNC_NAME) then write(std_out,*)"Enabling timelimit check in function: ",trim(FUNC_NAME)," with timelimit: ",trim(sec2str(get_timelimit())) end if
SOURCE
165 function enable_timelimit_in(abifunc) result(prev_func) 166 167 !Arguments ----------------------------------- 168 character(len=*),intent(in) :: abifunc 169 character(len=fnlen) :: prev_func 170 171 ! ************************************************************************* 172 173 if (WTIME_LIMIT > zero .and. TIMELIMIT_INABIFUNC == "__None__") TIMELIMIT_INABIFUNC = abifunc 174 prev_func = TIMELIMIT_INABIFUNC 175 176 end function enable_timelimit_in
m_exit/exit_check [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
exit_check
FUNCTION
This routine checks whether the CPU time limit is exceeded or not. If openexit is non-zero, it also checks the "filename" file for the "exit" character string in its first line and returns the location of the string on the line (0 if not found). Maps both strings to upper case before attempting to match them. Also checks for the existence of the "abinit.exit" file in the directory where the job was started. Finally, checks whether the CPU time limit was not exceeded. If one of these conditions occurs, will induce graceful exit of iterations.
INPUTS
cpus = CPU time limit filename = character string giving name of file to be opened iout = unit number to print output to openexit = if 1, open the "filename" and "abinit.exit" files comm=MPI communicator.
OUTPUT
iexit = index of "exit" on first line of file (0 if not found), or -1 if the exit was ordered through the existence of the "exit" file or -2 if the exit was ordered through the CPU time limit.
SOURCE
272 subroutine exit_check(cpus,filename,iexit,iout,comm,openexit) 273 274 !Arguments ------------------------------------ 275 integer,intent(in) :: comm 276 real(dp),intent(in) :: cpus 277 character(len=*),intent(in) :: filename 278 integer,intent(in) :: openexit,iout 279 integer,intent(out) :: iexit 280 281 !Local variables------------------------------- 282 !scalars 283 integer,parameter :: master=0 284 integer,save :: iexit_save=0 285 integer :: ierr,temp_unit,ierrmpi 286 logical :: ex 287 real(dp),save :: tcpu_last=zero 288 character(len=500) :: message 289 character(len=fnlen) :: line 290 character(len=4), parameter :: string='EXIT' 291 !arrays 292 real(dp) :: tsec(2) 293 294 ! ************************************************************************* 295 296 if (iexit_save==0) then 297 ! ABINIT will pass again in this routine even after exit call has been detected 298 299 if (xmpi_comm_rank(comm)==master) then 300 ! Master tests and broadcast the result to others 301 iexit=0 302 303 ! Is it worth to test the cpu time ? 304 tsec = zero 305 if (abs(cpus)>1.0d-5 .or. openexit==1) then 306 call timein(tsec(1),tsec(2)) 307 end if 308 309 ! A first way of exiting: the cpu time limit 310 if (abs(cpus)>1.0d-5) then 311 if(cpus<tsec(1))iexit=-2 312 end if 313 314 ! Test the content of files only when sufficient time (2 sec) has elapsed from last time it was tested. 315 if (openexit==1 .and. iexit==0 .and. tsec(1)-tcpu_last>two ) then 316 ! TODO Remove this approach. Use abinit.exit! 317 tcpu_last=tsec(1) 318 ! Open file and read first line as character string 319 if (open_file(filename,message,newunit=temp_unit,form='formatted',status='old') /= 0) then 320 ABI_ERROR(message) 321 end if 322 rewind (unit=temp_unit) 323 read (unit=temp_unit,fmt='(a)',iostat=ierr) line 324 if(ierr/=0)then 325 write(message, '(a,a,a,i5,a,a)' )& 326 & 'Problem when reading file=',TRIM(filename),'iostat =',ierr,ch10,& 327 & 'Action: check whether this file is OK.' 328 ABI_ERROR(message) 329 end if 330 ! Make a local copy of matching string of length equal to nonblank length of input string 331 ! Map to upper case 332 call inupper(line) 333 iexit=index(line,string) 334 close (unit=temp_unit) 335 336 ! This is another way of exiting : the previous one does not work 337 ! on some machines, may be because they keep a copy of the initial input file. 338 if(iexit==0)then 339 inquire(file='abinit.exit',exist=ex) 340 if(ex)iexit=-1 341 end if 342 343 end if 344 end if 345 346 call xmpi_bcast(iexit,master,comm,ierrmpi) 347 348 else 349 ! In case the exit mechanism has already been activated 350 iexit=iexit_save 351 end if 352 353 if (iexit/=0) then 354 if (iexit>0) write(message, '(a,a,a,a,a,a,a)' ) ch10,& 355 & ' chkexi: WARNING -',ch10,& 356 & ' Exit has been requested from file ',trim(filename),'.',ch10 357 if (iexit==-1) write(message, '(a,a,a,a,a)' ) ch10,& 358 & ' chkexi: WARNING -',ch10,& 359 & ' Exit has been requested from file "abinit.exit".',ch10 360 if (iexit==-2) write(message, '(a,a,a,a,a)' ) ch10,& 361 & ' chkexi: WARNING -',ch10,& 362 & ' Exit due to cpu time limit exceeded.',ch10 363 if (iout/=std_out) then 364 call wrtout(iout,message,'COLL') 365 end if 366 call wrtout(std_out, message,'COLL') 367 end if 368 369 iexit_save=iexit 370 371 end subroutine exit_check
m_exit/exit_init [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
exit_init
FUNCTION
Initialize the global variables of the modules. This is a collective function that should be called by all the nodes in COMM_WORLD
INPUTS
SOURCE
79 subroutine exit_init(time_limit) 80 81 !Arguments ------------------------------------ 82 real(dp),intent(in) :: time_limit 83 84 ! ************************************************************************* 85 86 WTIME_LIMIT = time_limit 87 WALL0 = abi_wtime() 88 89 end subroutine exit_init
m_exit/get_start_time [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
get_start_time
FUNCTION
Return the origin of execution time in seconds
SOURCE
237 real(dp) pure function get_start_time() 238 239 get_start_time = WALL0 240 241 end function get_start_time
m_exit/get_timelimit [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
get_timelimit
FUNCTION
Return the time limit in seconds
SOURCE
190 real(dp) pure function get_timelimit() 191 192 get_timelimit = WTIME_LIMIT 193 194 end function get_timelimit
m_exit/get_timelimit_string [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
get_timelimit_string
FUNCTION
Return the time limit in string form.
SOURCE
208 pure function get_timelimit_string() result(string) 209 210 !Local variables------------------------------- 211 !scalars 212 real(dp) :: timelimit 213 character(len=500) :: string 214 215 ! ************************************************************************* 216 217 ! Handle negative values 218 timelimit = get_timelimit() 219 if (timelimit > zero) then 220 string = sec2str(timelimit) 221 else 222 string = "0" 223 end if 224 225 end function get_timelimit_string
m_exit/have_timelimit_in [ Functions ]
[ Top ] [ m_exit ] [ Functions ]
NAME
have_timelimit_in
FUNCTION
Return .True. if timelimit is enabled in this caller
SOURCE
135 logical pure function have_timelimit_in(abifunc) result(ans) 136 137 !Arguments ----------------------------------- 138 character(len=*),intent(in) :: abifunc 139 140 ! ************************************************************************* 141 142 ans = WTIME_LIMIT > zero .and. abifunc == TIMELIMIT_INABIFUNC 143 144 end function have_timelimit_in