[3837] | 1 | MODULE job_timelimit_mod |
---|
| 2 | |
---|
| 3 | !*********************************************************************** |
---|
| 4 | ! DESCRIPTION: |
---|
| 5 | ! Retrieves the time limit (in seconds) for a given job ID via |
---|
| 6 | ! SLURM (squeue) or PBS/TORQUE (qstat). |
---|
| 7 | !*********************************************************************** |
---|
| 8 | |
---|
| 9 | implicit none |
---|
| 10 | |
---|
| 11 | real :: timelimit = 86400. ! Time limit for the job: 86400 s = 24 h by default |
---|
| 12 | real, parameter :: antetime = 3600. ! Anticipation time to prevent reaching the job time limit: 3600 s = 1 h by default |
---|
| 13 | logical :: timewall = .false. ! Flag to enable the program self-termination before timeout |
---|
| 14 | |
---|
| 15 | !======================================================================= |
---|
| 16 | contains |
---|
| 17 | !======================================================================= |
---|
| 18 | |
---|
| 19 | SUBROUTINE get_job_timelimit(arg) |
---|
| 20 | |
---|
| 21 | implicit none |
---|
| 22 | |
---|
| 23 | !---- Arguments |
---|
| 24 | character(*), intent(in) :: arg |
---|
| 25 | |
---|
| 26 | !---- Variables |
---|
| 27 | logical :: num_str |
---|
| 28 | character(256) :: chtimelimit ! Time limit for the job outputted by the SLURM or PBS/TORQUE command |
---|
| 29 | integer :: i, cstat, days, hours, minutes, seconds |
---|
| 30 | character(1) :: sep |
---|
| 31 | |
---|
| 32 | !---- Code |
---|
| 33 | ! Check that the job ID is numeric |
---|
| 34 | num_str = .true. |
---|
| 35 | do i = 1,len_trim(arg) |
---|
| 36 | if (arg(i:i) < '0' .or. arg(i:i) > '9') then |
---|
| 37 | num_str = .false. |
---|
| 38 | exit |
---|
| 39 | endif |
---|
| 40 | enddo |
---|
| 41 | if (.not. num_str) error stop 'Error: job ID must be numeric.' |
---|
| 42 | |
---|
| 43 | ! Try SLURM (squeue) |
---|
| 44 | call execute_command_line('squeue -j '//trim(adjustl(arg))//' -h --Format TimeLimit > tmp_cmdout.txt',cmdstat = cstat) |
---|
| 45 | if (cstat /= 0) then |
---|
| 46 | ! On failure, try PBS/TORQUE (qstat) |
---|
| 47 | call execute_command_line('qstat -f '//trim(adjustl(arg))//' | grep "Walltime" | awk ''{print $3}'' > tmp_cmdout.txt',cmdstat = cstat) |
---|
| 48 | if (cstat > 0) then |
---|
| 49 | error stop 'Error: command execution failed!' |
---|
| 50 | else if (cstat < 0) then |
---|
| 51 | error stop 'Error: command execution not supported (neither SLURM nor PBS/TORQUE is installed)!' |
---|
| 52 | endif |
---|
| 53 | endif |
---|
| 54 | |
---|
| 55 | ! Read the output |
---|
| 56 | open(1,file = 'tmp_cmdout.txt',status = 'old') |
---|
| 57 | read(1,'(a)') chtimelimit |
---|
| 58 | close(1) |
---|
| 59 | chtimelimit = trim(adjustl(chtimelimit)) |
---|
| 60 | |
---|
| 61 | ! Remove temporary file |
---|
| 62 | call execute_command_line('rm tmp_cmdout.txt',cmdstat = cstat) |
---|
| 63 | if (cstat > 0) then |
---|
| 64 | error stop 'Error: command execution failed!' |
---|
| 65 | else if (cstat < 0) then |
---|
| 66 | error stop 'Error: command execution not supported!' |
---|
| 67 | endif |
---|
| 68 | |
---|
| 69 | ! Parse D-HH:MM:SS, HH:MM:SS or MM:SS |
---|
| 70 | if (index(chtimelimit,'-') > 0) then ! Format "D-HH:MM:SS" |
---|
| 71 | read(chtimelimit,'(i1,a1,i2,a1,i2,a1,i2)') days, sep, hours, sep, minutes, sep, seconds |
---|
| 72 | timelimit = days*86400 + hours*3600 + minutes*60 + seconds |
---|
| 73 | else if (index(chtimelimit,':') > 0 .and. len_trim(chtimelimit) > 5) then ! Format "HH:MM:SS" |
---|
| 74 | read(chtimelimit,'(i2,a1,i2,a1,i2)') hours, sep, minutes, sep, seconds |
---|
| 75 | timelimit = hours*3600 + minutes*60 + seconds |
---|
| 76 | else ! Format "MM:SS" |
---|
| 77 | read(chtimelimit,'(i2,a1,i2)') minutes, sep, seconds |
---|
| 78 | timelimit = minutes*60 + seconds |
---|
| 79 | endif |
---|
| 80 | |
---|
| 81 | timewall = .true. |
---|
| 82 | |
---|
| 83 | END SUBROUTINE get_job_timelimit |
---|
| 84 | |
---|
| 85 | END MODULE job_timelimit_mod |
---|