(git:d1312bc)
Loading...
Searching...
No Matches
cp_external_control.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines to handle the external control of CP2K
10!> \par History
11!> - Moved from MODULE termination to here (18.02.2011,MK)
12!> - add communication control (20.02.2013 Mandes)
13!> \author Marcella Iannuzzi (10.03.2005,MI)
14! **************************************************************************************************
16
17 USE cp_files, ONLY: close_file,&
23 USE kinds, ONLY: default_string_length,&
24 dp
25 USE machine, ONLY: m_walltime
27#include "./base/base_uses.f90"
28
29 IMPLICIT NONE
30
31 PRIVATE
32
33 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_external_control'
34
35 PUBLIC :: external_control
36 PUBLIC :: set_external_comm
37
38 TYPE(mp_comm_type), SAVE :: external_comm
39 INTEGER, SAVE :: external_master_id = -1
40 INTEGER, SAVE :: scf_energy_message_tag = -1
41 INTEGER, SAVE :: exit_tag = -1
42
43CONTAINS
44
45! **************************************************************************************************
46!> \brief set the communicator to an external source or destination,
47!> to send messages (e.g. intermediate energies during scf) or
48!> reveive commands (e.g. aborting the calculation)
49!> \param comm ...
50!> \param in_external_master_id ...
51!> \param in_scf_energy_message_tag ...
52!> \param in_exit_tag ...
53!> \author Mandes 02.2013
54! **************************************************************************************************
55 SUBROUTINE set_external_comm(comm, in_external_master_id, &
56 in_scf_energy_message_tag, in_exit_tag)
57 CLASS(mp_comm_type), INTENT(IN) :: comm
58 INTEGER, INTENT(IN) :: in_external_master_id
59 INTEGER, INTENT(IN), OPTIONAL :: in_scf_energy_message_tag, in_exit_tag
60
61 cpassert(in_external_master_id >= 0)
62
63 external_comm = comm
64 external_master_id = in_external_master_id
65
66 IF (PRESENT(in_scf_energy_message_tag)) THEN
67 scf_energy_message_tag = in_scf_energy_message_tag
68 END IF
69 IF (PRESENT(in_exit_tag)) THEN
70 ! the exit tag should be different from the mpi_probe tag default
71 cpassert(in_exit_tag /= -1)
72 exit_tag = in_exit_tag
73 END IF
74 END SUBROUTINE set_external_comm
75
76! **************************************************************************************************
77!> \brief External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype
78!> command is sent the program stops at the level of $runtype
79!> when a general <PROJECT_NAME>.EXIT command is sent the program is stopped
80!> at all levels (at least those that call this function)
81!> if the file WAIT exists, the program waits here till it disappears
82!> \param should_stop ...
83!> \param flag ...
84!> \param globenv ...
85!> \param target_time ...
86!> \param start_time ...
87!> \param force_check ...
88!> \author MI (10.03.2005)
89! **************************************************************************************************
90 SUBROUTINE external_control(should_stop, flag, globenv, target_time, start_time, force_check)
91
92 LOGICAL, INTENT(OUT) :: should_stop
93 CHARACTER(LEN=*), INTENT(IN) :: flag
94 TYPE(global_environment_type), OPTIONAL, POINTER :: globenv
95 REAL(dp), OPTIONAL :: target_time, start_time
96 LOGICAL, OPTIONAL :: force_check
97
98 CHARACTER(LEN=*), PARAMETER :: routinen = 'external_control'
99
100 CHARACTER(LEN=default_string_length) :: exit_fname, exit_fname_level, &
101 exit_gname, exit_gname_level
102 INTEGER :: handle, i, tag, unit_number
103 LOGICAL :: should_wait
104 LOGICAL, SAVE :: check_always = .false.
105 REAL(kind=dp) :: my_start_time, my_target_time, t1, t2, &
106 time_check
107 REAL(kind=dp), SAVE :: t_last_file_check = 0.0_dp
108 TYPE(cp_logger_type), POINTER :: logger
109
110 CALL timeset(routinen, handle)
111
112 logger => cp_get_default_logger()
113 should_stop = .false.
114
115 IF (PRESENT(force_check)) THEN
116 IF (force_check) THEN
117 check_always = .true.
118 END IF
119 END IF
120
121 exit_gname = "EXIT"
122 exit_gname_level = trim(exit_gname)//"_"//trim(flag)
123 exit_fname = trim(logger%iter_info%project_name)//"."//trim(exit_gname)
124 exit_fname_level = trim(logger%iter_info%project_name)//"."//trim(exit_gname_level)
125
126 ! check for incomming messages and if it is tagged with the exit tag
127 IF (exit_tag /= -1) THEN
128 i = external_master_id
129 CALL external_comm%probe(source=i, tag=tag)
130 IF (tag == exit_tag) should_stop = .true.
131 END IF
132
133 IF (logger%para_env%is_source()) THEN
134 ! files will only be checked every 20 seconds, or if the clock wraps/does not exist,
135 ! otherwise 64 waters on 64 cores can spend up to 10% of time here, on lustre
136 ! however, if should_stop has been true, we should always check
137 ! (at each level scf, md, ... the file must be there to guarantee termination)
138 t1 = m_walltime()
139 IF (t1 > t_last_file_check + 20.0_dp .OR. t1 <= t_last_file_check .OR. check_always) THEN
140
141 t_last_file_check = t1
142 ! allows for halting execution for a while
143 ! this is useful to copy a consistent snapshot of the output
144 ! while a simulation is running
145 INQUIRE (file="WAIT", exist=should_wait)
146 IF (should_wait) THEN
147 CALL open_file(file_name="WAITING", file_status="UNKNOWN", &
148 file_form="FORMATTED", file_action="WRITE", &
149 unit_number=unit_number)
150 WRITE (unit=cp_logger_get_default_unit_nr(logger), fmt="(/,T2,A,/)") &
151 "*** waiting till the file WAIT has been removed ***"
152 DO
153 ! sleep a bit (to save the file system)
154 t1 = m_walltime()
155 DO i = 1, 100000000
156 t2 = m_walltime()
157 IF (t2 - t1 > 1.0_dp) EXIT
158 END DO
159 ! and ask again
160 INQUIRE (file="WAIT", exist=should_wait)
161 IF (.NOT. should_wait) EXIT
162 END DO
163 CALL close_file(unit_number=unit_number, file_status="DELETE")
164 END IF
165 ! EXIT control sequence
166 ! Check for <PROJECT_NAME>.EXIT_<FLAG>
167 IF (.NOT. should_stop) THEN
168 INQUIRE (file=exit_fname_level, exist=should_stop)
169 IF (should_stop) THEN
170 CALL open_file(file_name=exit_fname_level, unit_number=unit_number)
171 CALL close_file(unit_number=unit_number, file_status="DELETE")
172 WRITE (unit=cp_logger_get_default_unit_nr(logger), fmt="(/,T2,A,/)") &
173 "*** "//flag//" run terminated by external request ***"
174 END IF
175 END IF
176 ! Check for <PROJECT_NAME>.EXIT
177 IF (.NOT. should_stop) THEN
178 INQUIRE (file=exit_fname, exist=should_stop)
179 IF (should_stop) THEN
180 WRITE (unit=cp_logger_get_default_unit_nr(logger), fmt="(/,T2,A,/)") &
181 "*** "//trim(flag)//" run terminated by external request ***"
182 END IF
183 END IF
184 ! Check for EXIT_<FLAG>
185 IF (.NOT. should_stop) THEN
186 INQUIRE (file=exit_gname_level, exist=should_stop)
187 IF (should_stop) THEN
188 CALL open_file(file_name=exit_gname_level, unit_number=unit_number)
189 CALL close_file(unit_number=unit_number, file_status="DELETE")
190 WRITE (unit=cp_logger_get_default_unit_nr(logger), fmt="(/,T2,A,/)") &
191 "*** "//flag//" run terminated by external request ***"
192 END IF
193 END IF
194 ! Check for EXIT
195 IF (.NOT. should_stop) THEN
196 INQUIRE (file=exit_gname, exist=should_stop)
197 IF (should_stop) THEN
198 WRITE (unit=cp_logger_get_default_unit_nr(logger), fmt="(/,T2,A,/)") &
199 "*** "//trim(flag)//" run terminated by external request ***"
200 END IF
201 END IF
202 END IF
203
204 IF (PRESENT(target_time)) THEN
205 my_target_time = target_time
206 my_start_time = start_time
207 ELSE IF (PRESENT(globenv)) THEN
208 my_target_time = globenv%cp2k_target_time
209 my_start_time = globenv%cp2k_start_time
210 ELSE
211 ! If none of the two arguments is present abort.. This routine should always check about time.
212 cpabort("Neither target_time nor globenv exists for external_control")
213 END IF
214
215 IF ((.NOT. should_stop) .AND. (my_target_time > 0.0_dp)) THEN
216 ! Check for execution time
217 time_check = m_walltime() - my_start_time
218 IF (time_check > my_target_time) THEN
219 should_stop = .true.
220 WRITE (unit=cp_logger_get_default_unit_nr(logger), fmt="(/,T2,A,F12.3,A)") &
221 "*** "//trim(flag)//" run terminated - exceeded requested execution time:", &
222 my_target_time, " seconds", &
223 "*** Execution time now: ", time_check, " seconds"
224 END IF
225 END IF
226 END IF
227 CALL logger%para_env%bcast(should_stop)
228
229 check_always = should_stop
230
231 CALL timestop(handle)
232
233 END SUBROUTINE external_control
234
235END MODULE cp_external_control
236
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
subroutine, public set_external_comm(comm, in_external_master_id, in_scf_energy_message_tag, in_exit_tag)
set the communicator to an external source or destination, to send messages (e.g. intermediate energi...
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:311
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:122
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Define type storing the global information of a run. Keep the amount of stored data small....
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:141
Interface to the message passing library MPI.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
contains the initially parsed file and the initial parallel environment