TABLE OF CONTENTS


ABINIT/m_exit [ Modules ]

[ Top ] [ 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