(git:b279b6b)
swarm.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Swarm-framwork, provides a convenient master/worker architecture.
10 !> \author Ole Schuett
11 ! **************************************************************************************************
12 MODULE swarm
14  cp_logger_type
16  USE global_types, ONLY: global_environment_type
17  USE input_section_types, ONLY: section_type,&
18  section_vals_type,&
20  USE kinds, ONLY: default_string_length
21  USE message_passing, ONLY: mp_para_env_type
25  swarm_master_type
26  USE swarm_message, ONLY: swarm_message_add,&
28  swarm_message_get,&
29  swarm_message_type
30  USE swarm_mpi, ONLY: swarm_mpi_finalize,&
36  swarm_mpi_type
40  swarm_worker_type
41 #include "../base/base_uses.f90"
42 
43  IMPLICIT NONE
44  PRIVATE
45 
46  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'swarm'
47 
48  PUBLIC :: run_swarm
49 
50 CONTAINS
51 
52 ! **************************************************************************************************
53 !> \brief Central driver routine of the swarm framework, called by cp2k_runs.F
54 !> \param input_declaration ...
55 !> \param root_section ...
56 !> \param para_env ...
57 !> \param globenv ...
58 !> \param input_path ...
59 !> \author Ole Schuett
60 ! **************************************************************************************************
61  SUBROUTINE run_swarm(input_declaration, root_section, para_env, globenv, input_path)
62  TYPE(section_type), POINTER :: input_declaration
63  TYPE(section_vals_type), POINTER :: root_section
64  TYPE(mp_para_env_type), POINTER :: para_env
65  TYPE(global_environment_type), POINTER :: globenv
66  CHARACTER(LEN=*), INTENT(IN) :: input_path
67 
68  CHARACTER(len=*), PARAMETER :: routinen = 'run_swarm'
69 
70  INTEGER :: handle, iw, n_workers
71  TYPE(cp_logger_type), POINTER :: logger
72 
73  CALL timeset(routinen, handle)
74 
75  logger => cp_get_default_logger()
76  iw = cp_print_key_unit_nr(logger, root_section, &
77  "SWARM%PRINT%MASTER_RUN_INFO", extension=".masterLog")
78 
79  IF (iw > 0) WRITE (iw, "(A)") " SWARM| Ready to roll :-)"
80 
81  CALL section_vals_val_get(root_section, "SWARM%NUMBER_OF_WORKERS", &
82  i_val=n_workers)
83 
84  IF (n_workers == 1 .AND. para_env%num_pe == 1) THEN
85  IF (iw > 0) WRITE (iw, "(A)") " SWARM| Running in single worker mode."
86  CALL swarm_serial_driver(input_declaration, root_section, input_path, para_env, globenv)
87  ELSE
88  IF (iw > 0) WRITE (iw, "(A)") " SWARM| Running in master / workers mode."
89  !printkey iw passed on for output from swarm_mpi_init()
90  CALL swarm_parallel_driver(n_workers, input_declaration, root_section, input_path, para_env, globenv, iw)
91  END IF
92 
93  CALL timestop(handle)
94  END SUBROUTINE run_swarm
95 
96 ! **************************************************************************************************
97 !> \brief Special driver for using only a single worker.
98 !> \param input_declaration ...
99 !> \param root_section ...
100 !> \param input_path ...
101 !> \param para_env ...
102 !> \param globenv ...
103 !> \author Ole Schuett
104 ! **************************************************************************************************
105  SUBROUTINE swarm_serial_driver(input_declaration, root_section, input_path, para_env, globenv)
106  TYPE(section_type), POINTER :: input_declaration
107  TYPE(section_vals_type), POINTER :: root_section
108  CHARACTER(LEN=*), INTENT(IN) :: input_path
109  TYPE(mp_para_env_type), POINTER :: para_env
110  TYPE(global_environment_type), POINTER :: globenv
111 
112  INTEGER :: handle
113  LOGICAL :: should_stop
114  TYPE(swarm_master_type) :: master
115  TYPE(swarm_message_type) :: cmd, report
116  TYPE(swarm_worker_type) :: worker
117 
118  CALL swarm_master_init(master, para_env, globenv, root_section, n_workers=1)
119  CALL swarm_worker_init(worker, para_env, input_declaration, root_section, &
120  input_path, worker_id=1)
121 
122  CALL swarm_message_add(report, "worker_id", 1)
123  CALL swarm_message_add(report, "status", "initial_hello")
124 
125  should_stop = .false.
126  DO WHILE (.NOT. should_stop)
127  CALL timeset("swarm_worker_await_reply", handle)
128  CALL swarm_master_steer(master, report, cmd)
129  CALL timestop(handle)
130  CALL swarm_message_free(report)
131  CALL swarm_worker_execute(worker, cmd, report, should_stop)
132  CALL swarm_message_free(cmd)
133  END DO
134 
135  CALL swarm_message_free(report)
136  CALL swarm_worker_finalize(worker)
137  CALL swarm_master_finalize(master)
138 
139  END SUBROUTINE swarm_serial_driver
140 
141 ! **************************************************************************************************
142 !> \brief Normal driver routine for parallelized runs.
143 !> \param n_workers ...
144 !> \param input_declaration ...
145 !> \param root_section ...
146 !> \param input_path ...
147 !> \param para_env ...
148 !> \param globenv ...
149 !> \param iw ...
150 !> \author Ole Schuett
151 ! **************************************************************************************************
152  SUBROUTINE swarm_parallel_driver(n_workers, input_declaration, root_section, input_path, para_env, globenv, iw)
153  INTEGER, INTENT(IN) :: n_workers
154  TYPE(section_type), POINTER :: input_declaration
155  TYPE(section_vals_type), POINTER :: root_section
156  CHARACTER(LEN=*), INTENT(IN) :: input_path
157  TYPE(mp_para_env_type), POINTER :: para_env
158  TYPE(global_environment_type), POINTER :: globenv
159  INTEGER, INTENT(IN) :: iw
160 
161  INTEGER :: worker_id
162  TYPE(swarm_mpi_type) :: swarm_mpi
163 
164  CALL swarm_mpi_init(swarm_mpi, para_env, root_section, n_workers, worker_id, iw)
165 
166  IF (ASSOCIATED(swarm_mpi%worker)) THEN
167  CALL swarm_parallel_worker_driver(swarm_mpi, input_declaration, worker_id, root_section, input_path)
168  ELSE
169  CALL swarm_parallel_master_driver(swarm_mpi, n_workers, root_section, globenv)
170  END IF
171 
172  CALL swarm_mpi_finalize(swarm_mpi, root_section)
173 
174  END SUBROUTINE swarm_parallel_driver
175 
176 ! **************************************************************************************************
177 !> \brief Worker's driver routine for parallelized runs.
178 !> \param swarm_mpi ...
179 !> \param input_declaration ...
180 !> \param worker_id ...
181 !> \param root_section ...
182 !> \param input_path ...
183 !> \author Ole Schuett
184 ! **************************************************************************************************
185  SUBROUTINE swarm_parallel_worker_driver(swarm_mpi, input_declaration, worker_id, root_section, input_path)
186  TYPE(swarm_mpi_type), INTENT(IN) :: swarm_mpi
187  TYPE(section_type), POINTER :: input_declaration
188  INTEGER, INTENT(IN) :: worker_id
189  TYPE(section_vals_type), POINTER :: root_section
190  CHARACTER(LEN=*), INTENT(IN) :: input_path
191 
192  INTEGER :: handle
193  LOGICAL :: should_stop
194  TYPE(swarm_message_type) :: cmd, report
195  TYPE(swarm_worker_type) :: worker
196 
197  CALL swarm_worker_init(worker, swarm_mpi%worker, input_declaration, &
198  root_section, input_path, worker_id=worker_id)
199 
200  CALL swarm_message_add(report, "worker_id", worker_id)
201  CALL swarm_message_add(report, "status", "initial_hello")
202 
203  should_stop = .false.
204  DO WHILE (.NOT. should_stop)
205  CALL timeset("swarm_worker_await_reply", handle)
206  CALL swarm_mpi_send_report(swarm_mpi, report)
207  CALL swarm_message_free(report)
209  CALL timestop(handle)
210  CALL swarm_worker_execute(worker, cmd, report, should_stop)
211  CALL swarm_message_free(cmd)
212  END DO
213 
214  CALL swarm_message_free(report)
215  CALL swarm_worker_finalize(worker)
216 
217  END SUBROUTINE swarm_parallel_worker_driver
218 
219 ! **************************************************************************************************
220 !> \brief Master's driver routine for parallelized runs.
221 !> \param swarm_mpi ...
222 !> \param n_workers ...
223 !> \param root_section ...
224 !> \param globenv ...
225 !> \author Ole Schuett
226 ! **************************************************************************************************
227  SUBROUTINE swarm_parallel_master_driver(swarm_mpi, n_workers, root_section, globenv)
228  TYPE(swarm_mpi_type), INTENT(IN) :: swarm_mpi
229  INTEGER, INTENT(IN) :: n_workers
230  TYPE(section_vals_type), POINTER :: root_section
231  TYPE(global_environment_type), POINTER :: globenv
232 
233  CHARACTER(len=default_string_length) :: command
234  INTEGER :: i_shutdowns, j, wid
235  LOGICAL, DIMENSION(n_workers) :: is_waiting
236  TYPE(swarm_master_type) :: master
237  TYPE(swarm_message_type) :: cmd, report
238 
239  is_waiting(:) = .false.
240 
241  CALL swarm_master_init(master, swarm_mpi%master, globenv, root_section, n_workers)
242 
243  i_shutdowns = 0
244  j = 0
245 
246  DO WHILE (i_shutdowns < n_workers)
247  ! Each iteration if the loop does s.th. different depending on j.
248  ! First (j==0) it receives one report with (blocking) MPI,
249  ! then it searches through the list is_waiting.
250  j = mod(j + 1, n_workers + 1)
251  IF (j == 0) THEN
252  CALL swarm_mpi_recv_report(swarm_mpi, report)
253  ELSE IF (is_waiting(j)) THEN
254  is_waiting(j) = .false.
255  CALL swarm_message_add(report, "worker_id", j)
256  CALL swarm_message_add(report, "status", "wait_done")
257  ELSE
258  cycle
259  END IF
260 
261  CALL swarm_master_steer(master, report, cmd)
262  CALL swarm_message_free(report)
263 
264  CALL swarm_message_get(cmd, "command", command)
265  IF (trim(command) == "wait") THEN
266  CALL swarm_message_get(cmd, "worker_id", wid)
267  is_waiting(wid) = .true.
268  ELSE
270  IF (trim(command) == "shutdown") i_shutdowns = i_shutdowns + 1
271  END IF
272  CALL swarm_message_free(cmd)
273  END DO
274 
275  CALL swarm_master_finalize(master)
276 
277  END SUBROUTINE swarm_parallel_master_driver
278 
279 END MODULE swarm
280 
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
Define type storing the global information of a run. Keep the amount of stored data small....
Definition: global_types.F:21
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public default_string_length
Definition: kinds.F:57
Interface to the message passing library MPI.
Master's routines for the swarm-framework.
Definition: swarm_master.F:12
subroutine, public swarm_master_finalize(master)
Finalizes the swarm master.
Definition: swarm_master.F:317
subroutine, public swarm_master_steer(master, report, cmd)
Central steering routine of the swarm master.
Definition: swarm_master.F:224
subroutine, public swarm_master_init(master, para_env, globenv, root_section, n_workers)
Initializes the swarm master.
Definition: swarm_master.F:86
Swarm-message, a convenient data-container for with build-in serialization.
Definition: swarm_message.F:12
subroutine, public swarm_message_free(msg)
Deallocates all entries contained in a swarm-message.
Handles the MPI communication of the swarm framework.
Definition: swarm_mpi.F:12
subroutine, public swarm_mpi_init(swarm_mpi, world_para_env, root_section, n_workers, worker_id, iw)
Initialize MPI communicators for a swarm run.
Definition: swarm_mpi.F:70
subroutine, public swarm_mpi_send_command(swarm_mpi, cmd)
Sends a command via MPI.
Definition: swarm_mpi.F:365
subroutine, public swarm_mpi_recv_report(swarm_mpi, report)
Receives a report via MPI.
Definition: swarm_mpi.F:346
subroutine, public swarm_mpi_recv_command(swarm_mpi, cmd)
Receives a command via MPI and broadcasts it within a worker.
Definition: swarm_mpi.F:385
subroutine, public swarm_mpi_send_report(swarm_mpi, report)
Sends a report via MPI.
Definition: swarm_mpi.F:324
subroutine, public swarm_mpi_finalize(swarm_mpi, root_section)
Finalizes the MPI communicators of a swarm run.
Definition: swarm_mpi.F:269
Workers's routines for the swarm-framework.
Definition: swarm_worker.F:12
subroutine, public swarm_worker_finalize(worker)
Finalizes a swarm worker.
Definition: swarm_worker.F:137
subroutine, public swarm_worker_execute(worker, cmd, report, should_stop)
Central execute routine of the swarm worker.
Definition: swarm_worker.F:102
subroutine, public swarm_worker_init(worker, para_env, input_declaration, root_section, input_path, worker_id)
Initializes a swarm worker.
Definition: swarm_worker.F:64
Swarm-framwork, provides a convenient master/worker architecture.
Definition: swarm.F:12
subroutine, public run_swarm(input_declaration, root_section, para_env, globenv, input_path)
Central driver routine of the swarm framework, called by cp2k_runs.F.
Definition: swarm.F:62