Line data Source code
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 Sets up and terminates the global environment variables
10 : !> \par History
11 : !> - Merged with Quickstep MODULE start_program_run (17.01.2002,MK)
12 : !> - Compile information added (16.01.2002,MK)
13 : !> - Merged with MODULE cp2k_input, some rearrangements (30.10.2002,MK)
14 : !> - Update seed input (24.10.2016,MK)
15 : !> \author JGH,MK
16 : ! **************************************************************************************************
17 : MODULE environment
18 : USE bibliography, ONLY: Frigo2005,&
19 : Marek2014,&
20 : cite_reference
21 : USE cp2k_info, ONLY: &
22 : compile_arch, compile_date, compile_host, compile_revision, cp2k_flags, cp2k_home, &
23 : cp2k_version, cp2k_year, get_runtime_info, r_host_name, r_pid, r_user_name
24 : USE cp_error_handling, ONLY: warning_counter
25 : USE cp_files, ONLY: close_file,&
26 : get_data_dir,&
27 : open_file
28 : USE cp_fm_diag, ONLY: FM_DIAG_TYPE_CUSOLVER,&
29 : FM_DIAG_TYPE_DLAF,&
30 : FM_DIAG_TYPE_ELPA,&
31 : FM_DIAG_TYPE_SCALAPACK,&
32 : diag_finalize,&
33 : diag_init,&
34 : eps_check_diag_default
35 : USE cp_fm_diag_utils, ONLY: cp_fm_redistribute_init
36 : USE cp_fm_struct, ONLY: cp_fm_struct_config
37 : USE cp_fm_types, ONLY: cp_fm_get_mm_type,&
38 : cp_fm_setup
39 : USE cp_log_handling, ONLY: &
40 : cp_add_default_logger, cp_get_default_logger, cp_logger_create, &
41 : cp_logger_get_default_unit_nr, cp_logger_release, cp_logger_set, cp_logger_type, &
42 : cp_rm_default_logger, cp_to_string
43 : USE cp_output_handling, ONLY: cp_mpi_io_set,&
44 : cp_print_key_finished_output,&
45 : cp_print_key_unit_nr,&
46 : debug_print_level,&
47 : high_print_level,&
48 : low_print_level,&
49 : medium_print_level,&
50 : silent_print_level
51 : USE fft_tools, ONLY: fft3d,&
52 : finalize_fft,&
53 : init_fft
54 : USE force_env_types, ONLY: multiple_fe_list
55 : USE gamma, ONLY: deallocate_md_ftable
56 : USE global_types, ONLY: global_environment_type
57 : USE grid_api, ONLY: GRID_BACKEND_AUTO,&
58 : GRID_BACKEND_CPU,&
59 : GRID_BACKEND_DGEMM,&
60 : GRID_BACKEND_GPU,&
61 : GRID_BACKEND_HIP,&
62 : GRID_BACKEND_REF
63 : USE header, ONLY: cp2k_footer,&
64 : cp2k_header
65 : USE input_constants, ONLY: &
66 : callgraph_all, callgraph_none, do_cosma, do_cp2k, do_dgemm_blas, do_dgemm_spla, do_eip, &
67 : do_farming, do_fft_fftw3, do_fft_sg, do_fist, do_qs, do_scalapack, do_sirius, do_test, &
68 : energy_run, mol_dyn_run, none_run
69 : USE input_cp2k_global, ONLY: create_global_section
70 : USE input_enumeration_types, ONLY: enum_i2c,&
71 : enumeration_type
72 : USE input_keyword_types, ONLY: keyword_get,&
73 : keyword_type
74 : USE input_section_types, ONLY: &
75 : section_get_ival, section_get_keyword, section_get_lval, section_get_rval, &
76 : section_release, section_type, section_vals_get, section_vals_get_subs_vals, &
77 : section_vals_get_subs_vals3, section_vals_type, section_vals_val_get, section_vals_val_set
78 : USE kinds, ONLY: default_path_length,&
79 : default_string_length,&
80 : dp,&
81 : int_8,&
82 : print_kind_info
83 : USE local_gemm_api, ONLY: local_gemm_set_library
84 : USE machine, ONLY: &
85 : flush_should_flush, m_cpuid, m_cpuid_name, m_cpuid_static, m_cpuinfo, m_energy, &
86 : m_get_omp_stacksize, m_memory_details, m_procrun
87 : USE message_passing, ONLY: mp_collect_timings,&
88 : mp_para_env_type
89 : USE mp_perf_env, ONLY: add_mp_perf_env,&
90 : describe_mp_perf_env,&
91 : rm_mp_perf_env
92 : USE orbital_pointers, ONLY: deallocate_orbital_pointers,&
93 : init_orbital_pointers
94 : USE orbital_transformation_matrices, ONLY: deallocate_spherical_harmonics,&
95 : init_spherical_harmonics
96 : USE parallel_rng_types, ONLY: GAUSSIAN,&
97 : check_rng,&
98 : rng_stream_type,&
99 : write_rng_matrices
100 : USE physcon, ONLY: write_physcon
101 : USE reference_manager, ONLY: collect_citations_from_ranks,&
102 : print_all_references,&
103 : print_format_journal
104 : USE string_utilities, ONLY: ascii_to_string,&
105 : integer_to_string,&
106 : string_to_ascii
107 : USE timings, ONLY: add_timer_env,&
108 : global_timings_level,&
109 : rm_timer_env,&
110 : root_cp2k_name,&
111 : timings_setup_tracing
112 : USE timings_report, ONLY: cost_type_energy,&
113 : cost_type_time,&
114 : timings_report_callgraph,&
115 : timings_report_print
116 : USE voronoi_interface, ONLY: finalize_libvori
117 :
118 : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
119 : #include "./base/base_uses.f90"
120 :
121 : IMPLICIT NONE
122 :
123 : PRIVATE
124 :
125 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'environment'
126 :
127 : ! Public subroutines
128 :
129 : PUBLIC :: cp2k_finalize, cp2k_init, cp2k_read, cp2k_setup, cp2k_get_walltime
130 :
131 : CONTAINS
132 :
133 : ! **************************************************************************************************
134 : !> \brief Initializes a CP2K run (setting of the global environment variables)
135 : !> \param para_env ...
136 : !> \param output_unit ...
137 : !> \param globenv ...
138 : !> \param input_file_name ...
139 : !> \param wdir ...
140 : !> \par History
141 : !> JGH (28.11.2001) : default for pp_library_path
142 : !> - print keys added (17.01.2002, MK)
143 : !> - merged with cp2k_input (30.10.2002,MK)
144 : !> \author JGH,MK
145 : ! **************************************************************************************************
146 8989 : SUBROUTINE cp2k_init(para_env, output_unit, globenv, input_file_name, wdir)
147 :
148 : TYPE(mp_para_env_type), POINTER :: para_env
149 : INTEGER :: output_unit
150 : TYPE(global_environment_type), POINTER :: globenv
151 : CHARACTER(LEN=*) :: input_file_name
152 : CHARACTER(LEN=*), OPTIONAL :: wdir
153 :
154 : CHARACTER(LEN=10*default_string_length) :: cp_flags
155 : INTEGER :: i, ilen, my_output_unit
156 : TYPE(cp_logger_type), POINTER :: logger
157 :
158 : ! create a timer_env
159 :
160 8989 : CALL add_timer_env()
161 :
162 : ! Message passing performance
163 8989 : CALL add_mp_perf_env()
164 :
165 : ! Init the default logger
166 8989 : IF (para_env%is_source()) THEN
167 4598 : my_output_unit = output_unit
168 : ELSE
169 4391 : my_output_unit = -1
170 : END IF
171 8989 : NULLIFY (logger)
172 : CALL cp_logger_create(logger, para_env=para_env, &
173 : default_global_unit_nr=output_unit, &
174 8989 : close_global_unit_on_dealloc=.FALSE.)
175 8989 : CALL cp_add_default_logger(logger)
176 8989 : CALL cp_logger_release(logger)
177 :
178 : ! Initialize timing
179 8989 : CALL timeset(root_cp2k_name, globenv%handle)
180 :
181 : ! Print header
182 10029 : CALL cp2k_header(my_output_unit, wdir)
183 :
184 8989 : IF (my_output_unit > 0) THEN
185 : WRITE (UNIT=my_output_unit, FMT="(/,T2,A,T31,A50)") &
186 4598 : "CP2K| version string: ", ADJUSTR(TRIM(cp2k_version))
187 : WRITE (UNIT=my_output_unit, FMT="(T2,A,T41,A40)") &
188 4598 : "CP2K| source code revision number:", &
189 9196 : ADJUSTR(compile_revision)
190 4598 : cp_flags = cp2k_flags()
191 4598 : ilen = LEN_TRIM(cp_flags)
192 : WRITE (UNIT=my_output_unit, FMT="(T2,A)") &
193 4598 : "CP2K| "//cp_flags(1:73)
194 4598 : IF (ilen > 73) THEN
195 13794 : DO i = 0, (ilen - 75)/61
196 : WRITE (UNIT=my_output_unit, FMT="(T2,A)") &
197 13794 : "CP2K| "//TRIM(cp_flags(74 + i*61:MIN(74 + (i + 1)*61, ilen)))
198 : END DO
199 : END IF
200 : WRITE (UNIT=my_output_unit, FMT="(T2,A,T41,A40)") &
201 4598 : "CP2K| is freely available from ", &
202 9196 : ADJUSTR(TRIM(cp2k_home))
203 : WRITE (UNIT=my_output_unit, FMT="(T2,A,T31,A50)") &
204 4598 : "CP2K| Program compiled at", &
205 9196 : ADJUSTR(compile_date(1:MIN(50, LEN(compile_date))))
206 : WRITE (UNIT=my_output_unit, FMT="(T2,A,T31,A50)") &
207 4598 : "CP2K| Program compiled on", &
208 9196 : ADJUSTR(compile_host(1:MIN(50, LEN(compile_host))))
209 : WRITE (UNIT=my_output_unit, FMT="(T2,A,T31,A50)") &
210 4598 : "CP2K| Program compiled for", &
211 9196 : ADJUSTR(compile_arch(1:MIN(50, LEN(compile_arch))))
212 : WRITE (UNIT=my_output_unit, FMT="(T2,A,T31,A50)") &
213 4598 : "CP2K| Data directory path", &
214 9196 : ADJUSTR(TRIM(get_data_dir()))
215 : WRITE (UNIT=my_output_unit, FMT="(T2,A,T31,A50)") &
216 4598 : "CP2K| Input file name", &
217 9196 : ADJUSTR(TRIM(input_file_name))
218 4598 : FLUSH (my_output_unit) ! ignore &GLOBAL / FLUSH_SHOULD_FLUSH
219 : END IF
220 :
221 : #if defined(__FAST_MATH__)
222 : CALL cp_warn(__LOCATION__, &
223 : "During compilation one of the following flags was active:"// &
224 : " `-ffast-math` (GCC)"// &
225 : " `-hfpN` (Cray, N > 0, default N=2)"// &
226 : " This can lead to wrong results and numerical instabilities"// &
227 : " and is therefore no longer supported.")
228 :
229 : #if !defined(__FORCE_USE_FAST_MATH)
230 : #error "-ffast-math (GCC) or -hfpN (N>0, Cray) can lead to wrong results and numerical instabilities and are therefore no longer supported"
231 : #endif
232 : #endif
233 :
234 : #if defined(NDEBUG)
235 : #error "Please do not build CP2K with NDEBUG. There is no performance advantage and asserts will save your neck."
236 : #endif
237 :
238 8989 : END SUBROUTINE cp2k_init
239 :
240 : ! **************************************************************************************************
241 : !> \brief echoes the list of host names and pids
242 : !> \param para_env ...
243 : !> \param output_unit ...
244 : ! **************************************************************************************************
245 2 : SUBROUTINE echo_all_hosts(para_env, output_unit)
246 : TYPE(mp_para_env_type), POINTER :: para_env
247 : INTEGER :: output_unit
248 :
249 : CHARACTER(LEN=default_string_length) :: string
250 : INTEGER :: ipe
251 2 : INTEGER, ALLOCATABLE, DIMENSION(:) :: all_pid
252 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: all_host
253 :
254 : ! Print a list of all started processes
255 :
256 6 : ALLOCATE (all_pid(para_env%num_pe))
257 6 : all_pid(:) = 0
258 2 : all_pid(para_env%mepos + 1) = r_pid
259 :
260 2 : CALL para_env%sum(all_pid)
261 6 : ALLOCATE (all_host(30, para_env%num_pe))
262 126 : all_host(:, :) = 0
263 2 : CALL string_to_ascii(r_host_name, all_host(:, para_env%mepos + 1))
264 2 : CALL para_env%sum(all_host)
265 2 : IF (output_unit > 0) THEN
266 :
267 1 : WRITE (UNIT=output_unit, FMT="(T2,A)") ""
268 3 : DO ipe = 1, para_env%num_pe
269 2 : CALL ascii_to_string(all_host(:, ipe), string)
270 : WRITE (UNIT=output_unit, FMT="(T2,A,T63,I8,T71,I10)") &
271 : TRIM(r_user_name)//"@"//TRIM(string)// &
272 3 : " has created rank and process ", ipe - 1, all_pid(ipe)
273 : END DO
274 1 : WRITE (UNIT=output_unit, FMT="(T2,A)") ""
275 : END IF
276 2 : DEALLOCATE (all_pid)
277 2 : DEALLOCATE (all_host)
278 :
279 2 : END SUBROUTINE echo_all_hosts
280 :
281 : ! **************************************************************************************************
282 : !> \brief echoes the list the number of process per host
283 : !> \param para_env ...
284 : !> \param output_unit ...
285 : ! **************************************************************************************************
286 2 : SUBROUTINE echo_all_process_host(para_env, output_unit)
287 : TYPE(mp_para_env_type), POINTER :: para_env
288 : INTEGER :: output_unit
289 :
290 : CHARACTER(LEN=default_string_length) :: string, string_sec
291 : INTEGER :: ipe, jpe, nr_occu
292 2 : INTEGER, ALLOCATABLE, DIMENSION(:) :: all_pid
293 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: all_host
294 :
295 6 : ALLOCATE (all_host(30, para_env%num_pe))
296 126 : all_host(:, :) = 0
297 :
298 2 : IF (m_procrun(r_pid) .EQ. 1) THEN
299 2 : CALL string_to_ascii(r_host_name, all_host(:, para_env%mepos + 1))
300 2 : CALL para_env%sum(all_host)
301 : END IF
302 :
303 2 : IF (output_unit > 0) THEN
304 3 : ALLOCATE (all_pid(para_env%num_pe))
305 3 : all_pid(:) = 0
306 :
307 1 : WRITE (UNIT=output_unit, FMT="(T2,A)") ""
308 3 : DO ipe = 1, para_env%num_pe
309 2 : nr_occu = 0
310 3 : IF (all_pid(ipe) .NE. -1) THEN
311 1 : CALL ascii_to_string(all_host(:, ipe), string)
312 3 : DO jpe = 1, para_env%num_pe
313 2 : CALL ascii_to_string(all_host(:, jpe), string_sec)
314 3 : IF (string .EQ. string_sec) THEN
315 2 : nr_occu = nr_occu + 1
316 2 : all_pid(jpe) = -1
317 : END IF
318 : END DO
319 : WRITE (UNIT=output_unit, FMT="(T2,A,T63,I8,A)") &
320 : TRIM(r_user_name)//"@"//TRIM(string)// &
321 1 : " is running ", nr_occu, " processes"
322 1 : WRITE (UNIT=output_unit, FMT="(T2,A)") ""
323 : END IF
324 : END DO
325 1 : DEALLOCATE (all_pid)
326 :
327 : END IF
328 :
329 2 : DEALLOCATE (all_host)
330 :
331 2 : END SUBROUTINE echo_all_process_host
332 :
333 : ! **************************************************************************************************
334 : !> \brief read part of cp2k_init
335 : !> \param root_section ...
336 : !> \param para_env ...
337 : !> \param globenv the globenv
338 : !> \author fawzi
339 : !> \note
340 : !> The following routines need to be synchronized wrt. adding/removing
341 : !> of the default environments (logging, performance,error):
342 : !> environment:cp2k_init, environment:cp2k_finalize,
343 : !> f77_interface:f_env_add_defaults, f77_interface:f_env_rm_defaults,
344 : !> f77_interface:create_force_env, f77_interface:destroy_force_env
345 : ! **************************************************************************************************
346 8989 : SUBROUTINE cp2k_read(root_section, para_env, globenv)
347 :
348 : TYPE(section_vals_type), POINTER :: root_section
349 : TYPE(mp_para_env_type), POINTER :: para_env
350 : TYPE(global_environment_type), POINTER :: globenv
351 :
352 : CHARACTER(LEN=3*default_string_length) :: message
353 : CHARACTER(len=default_string_length) :: c_val
354 : INTEGER :: i, iw
355 : TYPE(cp_logger_type), POINTER :: logger
356 :
357 : ! Read the input/output section
358 :
359 8989 : logger => cp_get_default_logger()
360 :
361 : ! try to use better names for the local log if it is not too late
362 : CALL section_vals_val_get(root_section, "GLOBAL%OUTPUT_FILE_NAME", &
363 8989 : c_val=c_val)
364 8989 : IF (c_val /= "") THEN
365 : CALL cp_logger_set(logger, &
366 144 : local_filename=TRIM(c_val)//"_localLog")
367 : END IF
368 :
369 : ! Process project name
370 8989 : CALL section_vals_val_get(root_section, "GLOBAL%PROJECT", c_val=c_val)
371 8989 : IF (INDEX(c_val(:LEN_TRIM(c_val)), " ") > 0) THEN
372 : message = "Project name <"//TRIM(c_val)// &
373 2 : "> contains spaces which will be replaced with underscores"
374 2 : CPWARN(TRIM(message))
375 24 : DO i = 1, LEN_TRIM(c_val)
376 : ! Replace space with underscore
377 24 : IF (c_val(i:i) == " ") c_val(i:i) = "_"
378 : END DO
379 2 : CALL section_vals_val_set(root_section, "GLOBAL%PROJECT", c_val=TRIM(c_val))
380 : END IF
381 8989 : IF (c_val /= "") THEN
382 8989 : CALL cp_logger_set(logger, local_filename=TRIM(c_val)//"_localLog")
383 : END IF
384 8989 : logger%iter_info%project_name = c_val
385 :
386 8989 : CALL section_vals_val_get(root_section, "GLOBAL%PRINT_LEVEL", i_val=logger%iter_info%print_level)
387 :
388 : ! Read the CP2K section
389 8989 : CALL read_cp2k_section(root_section, para_env, globenv)
390 :
391 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PRINT/BASIC_DATA_TYPES", &
392 8989 : extension=".Log")
393 8989 : IF (iw > 0) CALL print_kind_info(iw)
394 : CALL cp_print_key_finished_output(iw, logger, root_section, &
395 8989 : "GLOBAL%PRINT/BASIC_DATA_TYPES")
396 :
397 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PRINT/PHYSCON", &
398 8989 : extension=".Log")
399 8989 : IF (iw > 0) CALL write_physcon(iw)
400 : CALL cp_print_key_finished_output(iw, logger, root_section, &
401 8989 : "GLOBAL%PRINT/PHYSCON")
402 :
403 8989 : END SUBROUTINE cp2k_read
404 :
405 : ! **************************************************************************************************
406 : !> \brief globenv initializations that need the input and error
407 : !> \param root_section ...
408 : !> \param para_env ...
409 : !> \param globenv the global environment to initialize
410 : !> \author fawzi
411 : !> \note
412 : !> if possible do the initializations here as the environment
413 : !> (error,...) is setup, instead of cp2k_init
414 : ! **************************************************************************************************
415 17978 : SUBROUTINE cp2k_setup(root_section, para_env, globenv)
416 :
417 : TYPE(section_vals_type), POINTER :: root_section
418 : TYPE(mp_para_env_type), POINTER :: para_env
419 : TYPE(global_environment_type), POINTER :: globenv
420 :
421 : INTEGER :: iw, maxl
422 8989 : INTEGER, DIMENSION(:), POINTER :: seed_vals
423 : REAL(KIND=dp), DIMENSION(3, 2) :: initial_seed
424 : TYPE(cp_logger_type), POINTER :: logger
425 :
426 8989 : NULLIFY (logger)
427 17978 : logger => cp_get_default_logger()
428 :
429 : ! Initialize the parallel random number generator
430 :
431 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PRINT/RNG_MATRICES", &
432 8989 : extension=".Log")
433 8989 : IF (iw > 0) THEN
434 1 : CALL write_rng_matrices(iw)
435 : END IF
436 :
437 : CALL cp_print_key_finished_output(iw, logger, root_section, &
438 8989 : "GLOBAL%PRINT/RNG_MATRICES")
439 :
440 : ! Initialize a global normally Gaussian distributed (pseudo)random number stream
441 :
442 8989 : CALL section_vals_val_get(root_section, "GLOBAL%SEED", i_vals=seed_vals)
443 8989 : IF (SIZE(seed_vals) == 1) THEN
444 80901 : initial_seed(:, :) = REAL(seed_vals(1), KIND=dp)
445 0 : ELSE IF (SIZE(seed_vals) == 6) THEN
446 0 : initial_seed(1:3, 1:2) = RESHAPE(REAL(seed_vals(:), KIND=dp), (/3, 2/))
447 : ELSE
448 0 : CPABORT("Supply exactly 1 or 6 arguments for SEED in &GLOBAL only!")
449 : END IF
450 :
451 : globenv%gaussian_rng_stream = rng_stream_type( &
452 : name="Global Gaussian random numbers", &
453 : distribution_type=GAUSSIAN, &
454 : seed=initial_seed, &
455 8989 : extended_precision=.TRUE.)
456 :
457 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PRINT/RNG_CHECK", &
458 8989 : extension=".Log")
459 8989 : IF (iw > 0) THEN
460 1 : CALL check_rng(iw, para_env%is_source())
461 : END IF
462 :
463 : CALL cp_print_key_finished_output(iw, logger, root_section, &
464 8989 : "GLOBAL%PRINT/RNG_CHECK")
465 :
466 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PRINT/GLOBAL_GAUSSIAN_RNG", &
467 8989 : extension=".Log")
468 8989 : IF (iw > 0) &
469 1 : CALL globenv%gaussian_rng_stream%write(iw, write_all=.TRUE.)
470 :
471 : CALL cp_print_key_finished_output(iw, logger, root_section, &
472 8989 : "GLOBAL%PRINT/GLOBAL_GAUSSIAN_RNG")
473 :
474 8989 : CALL section_vals_val_get(root_section, "GLOBAL%PRINT%SPHERICAL_HARMONICS", i_val=maxl)
475 8989 : IF (maxl >= 0) THEN
476 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PRINT", &
477 2 : extension=".Log")
478 2 : CALL init_orbital_pointers(maxl)
479 2 : CALL init_spherical_harmonics(maxl, iw)
480 2 : CALL deallocate_spherical_harmonics()
481 2 : CALL deallocate_orbital_pointers()
482 : CALL cp_print_key_finished_output(iw, logger, root_section, &
483 2 : "GLOBAL%PRINT")
484 : END IF
485 :
486 8989 : END SUBROUTINE cp2k_setup
487 :
488 : ! **************************************************************************************************
489 : !> \brief read the global section of new input
490 : !> \param root_section ...
491 : !> \param para_env ...
492 : !> \param globenv ...
493 : !> \par History
494 : !> 06-2005 [created]
495 : !> \author MI
496 : !> \note
497 : !> Should not be required anymore once everything is converted
498 : !> to get information directly from the input structure
499 : ! **************************************************************************************************
500 107868 : SUBROUTINE read_global_section(root_section, para_env, globenv)
501 :
502 : TYPE(section_vals_type), POINTER :: root_section
503 : TYPE(mp_para_env_type), POINTER :: para_env
504 : TYPE(global_environment_type), POINTER :: globenv
505 :
506 : CHARACTER(LEN=6), PARAMETER :: start_section_label = "GLOBAL"
507 :
508 : CHARACTER(len=13) :: omp_stacksize, tracing_string
509 : CHARACTER(len=6) :: print_level_string
510 : CHARACTER(len=default_path_length) :: basis_set_file_name, coord_file_name, &
511 : mm_potential_file_name, &
512 : potential_file_name
513 : CHARACTER(LEN=default_string_length) :: env_num, model_name, project_name
514 : CHARACTER(LEN=default_string_length), &
515 8989 : DIMENSION(:), POINTER :: trace_routines
516 : INTEGER :: cpuid, cpuid_static, i_dgemm, i_diag, i_fft, i_grid_backend, iforce_eval, &
517 : method_name_id, n_rep_val, nforce_eval, num_threads, output_unit, print_level, trace_max, &
518 : unit_nr
519 : INTEGER(kind=int_8) :: Buffers, Buffers_avr, Buffers_max, Buffers_min, Cached, Cached_avr, &
520 : Cached_max, Cached_min, MemFree, MemFree_avr, MemFree_max, MemFree_min, MemLikelyFree, &
521 : MemLikelyFree_avr, MemLikelyFree_max, MemLikelyFree_min, MemTotal, MemTotal_avr, &
522 : MemTotal_max, MemTotal_min, Slab, Slab_avr, Slab_max, Slab_min, SReclaimable, &
523 : SReclaimable_avr, SReclaimable_max, SReclaimable_min
524 8989 : INTEGER, DIMENSION(:), POINTER :: i_force_eval
525 : LOGICAL :: ata, do_echo_all_hosts, efl, explicit, &
526 : flag, report_maxloc, trace, &
527 : trace_master
528 : TYPE(cp_logger_type), POINTER :: logger
529 : TYPE(enumeration_type), POINTER :: enum1, enum2
530 : TYPE(keyword_type), POINTER :: keyword
531 : TYPE(section_type), POINTER :: section
532 : TYPE(section_vals_type), POINTER :: dft_section, force_env_sections, &
533 : global_section, qmmm_section, &
534 : subsys_section
535 :
536 8989 : NULLIFY (dft_section, global_section, i_force_eval)
537 :
538 17978 : logger => cp_get_default_logger()
539 8989 : global_section => section_vals_get_subs_vals(root_section, "GLOBAL")
540 8989 : CALL section_vals_val_get(global_section, "BLACS_GRID", i_val=globenv%blacs_grid_layout)
541 8989 : CALL section_vals_val_get(global_section, "BLACS_REPEATABLE", l_val=globenv%blacs_repeatable)
542 8989 : CALL section_vals_val_get(global_section, "PREFERRED_DIAG_LIBRARY", i_val=i_diag)
543 8989 : CALL section_vals_val_get(global_section, "PREFERRED_DGEMM_LIBRARY", i_val=i_dgemm)
544 8989 : CALL section_vals_val_get(global_section, "EPS_CHECK_DIAG", r_val=globenv%eps_check_diag)
545 8989 : CALL section_vals_val_get(global_section, "ENABLE_MPI_IO", l_val=flag)
546 8989 : CALL cp_mpi_io_set(flag)
547 8989 : CALL section_vals_val_get(global_section, "ELPA_KERNEL", i_val=globenv%k_elpa)
548 8989 : CALL section_vals_val_get(global_section, "ELPA_NEIGVEC_MIN", i_val=globenv%elpa_neigvec_min)
549 8989 : CALL section_vals_val_get(global_section, "ELPA_QR", l_val=globenv%elpa_qr)
550 8989 : CALL section_vals_val_get(global_section, "ELPA_QR_UNSAFE", l_val=globenv%elpa_qr_unsafe)
551 8989 : unit_nr = cp_print_key_unit_nr(logger, global_section, "PRINT_ELPA", extension=".Log")
552 8989 : IF (unit_nr > 0) globenv%elpa_print = .TRUE.
553 8989 : CALL cp_print_key_finished_output(unit_nr, logger, global_section, "PRINT_ELPA")
554 8989 : CALL section_vals_val_get(global_section, "DLAF_NEIGVEC_MIN", i_val=globenv%dlaf_neigvec_min)
555 8989 : CALL section_vals_val_get(global_section, "PREFERRED_FFT_LIBRARY", i_val=i_fft)
556 8989 : CALL section_vals_val_get(global_section, "PRINT_LEVEL", i_val=print_level)
557 8989 : CALL section_vals_val_get(global_section, "PROGRAM_NAME", i_val=globenv%prog_name_id)
558 8989 : CALL section_vals_val_get(global_section, "FFT_POOL_SCRATCH_LIMIT", i_val=globenv%fft_pool_scratch_limit)
559 8989 : CALL section_vals_val_get(global_section, "FFTW_PLAN_TYPE", i_val=globenv%fftw_plan_type)
560 8989 : CALL section_vals_val_get(global_section, "PROJECT_NAME", c_val=project_name)
561 8989 : CALL section_vals_val_get(global_section, "FFTW_WISDOM_FILE_NAME", c_val=globenv%fftw_wisdom_file_name)
562 8989 : CALL section_vals_val_get(global_section, "RUN_TYPE", i_val=globenv%run_type_id)
563 : CALL cp2k_get_walltime(section=global_section, keyword_name="WALLTIME", &
564 8989 : walltime=globenv%cp2k_target_time)
565 8989 : CALL section_vals_val_get(global_section, "TRACE", l_val=trace)
566 8989 : CALL section_vals_val_get(global_section, "TRACE_MASTER", l_val=trace_MASTER)
567 8989 : CALL section_vals_val_get(global_section, "TRACE_MAX", i_val=trace_max)
568 8989 : CALL section_vals_val_get(global_section, "TRACE_ROUTINES", explicit=explicit)
569 8989 : IF (explicit) THEN
570 0 : CALL section_vals_val_get(global_section, "TRACE_ROUTINES", c_vals=trace_routines)
571 : ELSE
572 8989 : NULLIFY (trace_routines)
573 : END IF
574 8989 : CALL section_vals_val_get(global_section, "FLUSH_SHOULD_FLUSH", l_val=flush_should_flush)
575 8989 : CALL section_vals_val_get(global_section, "ECHO_ALL_HOSTS", l_val=do_echo_all_hosts)
576 8989 : report_maxloc = section_get_lval(global_section, "TIMINGS%REPORT_MAXLOC")
577 8989 : global_timings_level = section_get_ival(global_section, "TIMINGS%TIMINGS_LEVEL")
578 8989 : do_echo_all_hosts = do_echo_all_hosts .OR. report_maxloc
579 8989 : force_env_sections => section_vals_get_subs_vals(root_section, "FORCE_EVAL")
580 8989 : CALL section_vals_get(force_env_sections, n_repetition=nforce_eval)
581 : output_unit = cp_print_key_unit_nr(logger, global_section, "PROGRAM_RUN_INFO", &
582 8989 : extension=".log")
583 :
584 8989 : CALL fm_setup(global_section)
585 8989 : CALL fm_diag_rules_setup(global_section)
586 8989 : CALL dgemm_setup(global_section)
587 :
588 8989 : IF (trace .AND. (.NOT. trace_master .OR. para_env%mepos == 0)) THEN
589 0 : unit_nr = -1
590 0 : IF (logger%para_env%is_source() .OR. .NOT. trace_master) &
591 0 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
592 0 : WRITE (tracing_string, "(I6.6,A1,I6.6)") para_env%mepos, ":", para_env%num_pe
593 0 : IF (ASSOCIATED(trace_routines)) THEN
594 0 : CALL timings_setup_tracing(trace_max, unit_nr, tracing_string, trace_routines)
595 : ELSE
596 0 : CALL timings_setup_tracing(trace_max, unit_nr, tracing_string)
597 : END IF
598 : END IF
599 :
600 8989 : CALL section_vals_val_get(global_section, "TIMINGS%TIME_MPI", l_val=mp_collect_timings)
601 :
602 188 : SELECT CASE (i_diag)
603 : CASE (FM_DIAG_TYPE_SCALAPACK)
604 188 : globenv%diag_library = "ScaLAPACK"
605 : CASE (FM_DIAG_TYPE_ELPA)
606 8801 : globenv%diag_library = "ELPA"
607 8801 : CALL cite_reference(Marek2014)
608 : CASE (FM_DIAG_TYPE_CUSOLVER)
609 0 : globenv%diag_library = "cuSOLVER"
610 : CASE (FM_DIAG_TYPE_DLAF)
611 0 : globenv%diag_library = "DLAF"
612 : ! TODO: Add citation when available
613 : CASE DEFAULT
614 8989 : CPABORT("Unknown diagonalization library specified")
615 : END SELECT
616 :
617 8 : SELECT CASE (i_fft)
618 : CASE (do_fft_sg)
619 8 : globenv%default_fft_library = "FFTSG"
620 : CASE (do_fft_fftw3)
621 8981 : globenv%default_fft_library = "FFTW3"
622 8981 : CALL cite_reference(Frigo2005)
623 : CASE DEFAULT
624 8989 : CPABORT("Unknown FFT library specified")
625 : END SELECT
626 :
627 0 : SELECT CASE (i_dgemm)
628 : CASE (do_dgemm_spla)
629 0 : globenv%default_dgemm_library = "SPLA"
630 : CASE (do_dgemm_blas)
631 8989 : globenv%default_dgemm_library = "BLAS"
632 : CASE DEFAULT
633 8989 : CPABORT("Unknown DGEMM library specified")
634 : END SELECT
635 :
636 8989 : IF (globenv%run_type_id == 0) THEN
637 0 : SELECT CASE (globenv%prog_name_id)
638 : CASE (do_farming, do_test)
639 0 : globenv%run_type_id = none_run
640 : CASE (do_cp2k)
641 0 : IF (nforce_eval /= 1) THEN
642 : ! multiple force_eval corresponds at the moment to RESPA calculations only
643 : ! default MD
644 0 : globenv%run_type_id = mol_dyn_run
645 : ELSE
646 0 : CALL section_vals_val_get(force_env_sections, "METHOD", i_val=method_name_id)
647 0 : SELECT CASE (method_name_id)
648 : CASE (do_fist)
649 0 : globenv%run_type_id = mol_dyn_run
650 : CASE (do_eip)
651 0 : globenv%run_type_id = mol_dyn_run
652 : CASE (do_qs)
653 0 : globenv%run_type_id = energy_run
654 : CASE (do_sirius)
655 0 : globenv%run_type_id = energy_run
656 : END SELECT
657 : END IF
658 : END SELECT
659 : END IF
660 :
661 8989 : IF (globenv%prog_name_id == do_farming .AND. globenv%run_type_id /= none_run) THEN
662 0 : CPABORT("FARMING program supports only NONE as run type")
663 : END IF
664 :
665 8989 : IF (globenv%prog_name_id == do_test .AND. globenv%run_type_id /= none_run) &
666 0 : CPABORT("TEST program supports only NONE as run type")
667 :
668 8989 : CALL m_memory_details(MemTotal, MemFree, Buffers, Cached, Slab, SReclaimable, MemLikelyFree)
669 8989 : MemTotal_avr = MemTotal
670 8989 : MemFree_avr = MemFree
671 8989 : Buffers_avr = Buffers
672 8989 : Cached_avr = Cached
673 8989 : Slab_avr = Slab
674 8989 : SReclaimable_avr = SReclaimable
675 8989 : MemLikelyFree_avr = MemLikelyFree
676 8989 : CALL para_env%sum(MemTotal_avr); MemTotal_avr = MemTotal_avr/para_env%num_pe/1024
677 8989 : CALL para_env%sum(MemFree_avr); MemFree_avr = MemFree_avr/para_env%num_pe/1024
678 8989 : CALL para_env%sum(Buffers_avr); Buffers_avr = Buffers_avr/para_env%num_pe/1024
679 8989 : CALL para_env%sum(Cached_avr); Cached_avr = Cached_avr/para_env%num_pe/1024
680 8989 : CALL para_env%sum(Slab_avr); Slab_avr = Slab_avr/para_env%num_pe/1024
681 8989 : CALL para_env%sum(SReclaimable_avr); SReclaimable_avr = SReclaimable_avr/para_env%num_pe/1024
682 8989 : CALL para_env%sum(MemLikelyFree_avr); MemLikelyFree_avr = MemLikelyFree_avr/para_env%num_pe/1024
683 :
684 8989 : MemTotal_min = -MemTotal
685 8989 : MemFree_min = -MemFree
686 8989 : Buffers_min = -Buffers
687 8989 : Cached_min = -Cached
688 8989 : Slab_min = -Slab
689 8989 : SReclaimable_min = -SReclaimable
690 8989 : MemLikelyFree_min = -MemLikelyFree
691 8989 : CALL para_env%max(MemTotal_min); MemTotal_min = -MemTotal_min/1024
692 8989 : CALL para_env%max(MemFree_min); MemFree_min = -MemFree_min/1024
693 8989 : CALL para_env%max(Buffers_min); Buffers_min = -Buffers_min/1024
694 8989 : CALL para_env%max(Cached_min); Cached_min = -Cached_min/1024
695 8989 : CALL para_env%max(Slab_min); Slab_min = -Slab_min/1024
696 8989 : CALL para_env%max(SReclaimable_min); SReclaimable_min = -SReclaimable_min/1024
697 8989 : CALL para_env%max(MemLikelyFree_min); MemLikelyFree_min = -MemLikelyFree_min/1024
698 :
699 8989 : MemTotal_max = MemTotal
700 8989 : MemFree_max = MemFree
701 8989 : Buffers_max = Buffers
702 8989 : Cached_max = Cached
703 8989 : Slab_max = Slab
704 8989 : SReclaimable_max = SReclaimable
705 8989 : MemLikelyFree_max = MemLikelyFree
706 8989 : CALL para_env%max(MemTotal_max); MemTotal_max = MemTotal_max/1024
707 8989 : CALL para_env%max(MemFree_max); MemFree_max = MemFree_max/1024
708 8989 : CALL para_env%max(Buffers_max); Buffers_max = Buffers_max/1024
709 8989 : CALL para_env%max(Cached_max); Cached_max = Cached_max/1024
710 8989 : CALL para_env%max(Slab_max); Slab_max = Slab_max/1024
711 8989 : CALL para_env%max(SReclaimable_max); SReclaimable_max = SReclaimable_max/1024
712 8989 : CALL para_env%max(MemLikelyFree_max); MemLikelyFree_max = MemLikelyFree_max/1024
713 :
714 8989 : MemTotal = MemTotal/1024
715 8989 : MemFree = MemFree/1024
716 8989 : Buffers = Buffers/1024
717 8989 : Cached = Cached/1024
718 8989 : Slab = Slab/1024
719 8989 : SReclaimable = SReclaimable/1024
720 8989 : MemLikelyFree = MemLikelyFree/1024
721 :
722 : ! Print a list of all started processes
723 8989 : IF (do_echo_all_hosts) THEN
724 2 : CALL echo_all_hosts(para_env, output_unit)
725 :
726 : ! Print the number of processes per host
727 2 : CALL echo_all_process_host(para_env, output_unit)
728 : END IF
729 :
730 8989 : num_threads = 1
731 8989 : !$ num_threads = omp_get_max_threads()
732 8989 : IF (output_unit > 0) THEN
733 4598 : WRITE (UNIT=output_unit, FMT=*)
734 4598 : CALL multiple_fe_list(force_env_sections, root_section, i_force_eval, nforce_eval)
735 9138 : DO iforce_eval = 1, nforce_eval
736 : dft_section => section_vals_get_subs_vals3(force_env_sections, "DFT", &
737 4540 : i_rep_section=i_force_eval(iforce_eval))
738 : qmmm_section => section_vals_get_subs_vals3(force_env_sections, "QMMM", &
739 4540 : i_rep_section=i_force_eval(iforce_eval))
740 : CALL section_vals_val_get(dft_section, "BASIS_SET_FILE_NAME", &
741 4540 : c_val=basis_set_file_name)
742 : CALL section_vals_val_get(dft_section, "POTENTIAL_FILE_NAME", &
743 4540 : c_val=potential_file_name)
744 :
745 : CALL section_vals_val_get(qmmm_section, "MM_POTENTIAL_FILE_NAME", &
746 4540 : c_val=mm_potential_file_name)
747 : ! SUBSYS - If any
748 : subsys_section => section_vals_get_subs_vals3(force_env_sections, "SUBSYS", &
749 4540 : i_rep_section=i_force_eval(iforce_eval))
750 4540 : CALL section_vals_get(subsys_section, explicit=explicit)
751 4540 : coord_file_name = "__STD_INPUT__"
752 4540 : IF (explicit) THEN
753 : CALL section_vals_val_get(subsys_section, "TOPOLOGY%COORD_FILE_NAME", &
754 4433 : n_rep_val=n_rep_val)
755 4433 : IF (n_rep_val == 1) THEN
756 : CALL section_vals_val_get(subsys_section, "TOPOLOGY%COORD_FILE_NAME", &
757 884 : c_val=coord_file_name)
758 : END IF
759 : END IF
760 4540 : CALL integer_to_string(i_force_eval(iforce_eval), env_num)
761 :
762 : WRITE (UNIT=output_unit, FMT="(T2,A,T41,A)") &
763 4540 : start_section_label//"| Force Environment number", &
764 4540 : ADJUSTR(env_num(:40)), &
765 4540 : start_section_label//"| Basis set file name", &
766 4540 : ADJUSTR(basis_set_file_name(:40)), &
767 4540 : start_section_label//"| Potential file name", &
768 4540 : ADJUSTR(potential_file_name(:40)), &
769 4540 : start_section_label//"| MM Potential file name", &
770 4540 : ADJUSTR(mm_potential_file_name(:40)), &
771 4540 : start_section_label//"| Coordinate file name", &
772 18218 : ADJUSTR(coord_file_name(:40))
773 : END DO
774 4598 : DEALLOCATE (i_force_eval)
775 :
776 4598 : NULLIFY (enum1, enum2, keyword, section)
777 4598 : CALL create_global_section(section)
778 4598 : keyword => section_get_keyword(section, "PROGRAM_NAME")
779 4598 : CALL keyword_get(keyword, enum=enum1)
780 4598 : keyword => section_get_keyword(section, "RUN_TYPE")
781 4598 : CALL keyword_get(keyword, enum=enum2)
782 :
783 : WRITE (UNIT=output_unit, FMT="(T2,A,T41,A40)") &
784 4598 : start_section_label//"| Method name", &
785 4598 : ADJUSTR(TRIM(enum_i2c(enum1, globenv%prog_name_id))), &
786 4598 : start_section_label//"| Project name", &
787 4598 : ADJUSTR(project_name(:40)), &
788 4598 : start_section_label//"| Run type", &
789 4598 : ADJUSTR(TRIM(enum_i2c(enum2, globenv%run_type_id))), &
790 4598 : start_section_label//"| FFT library", &
791 4598 : ADJUSTR(globenv%default_fft_library(:40)), &
792 4598 : start_section_label//"| Diagonalization library", &
793 4598 : ADJUSTR(globenv%diag_library(:40)), &
794 4598 : start_section_label//"| DGEMM library", &
795 9196 : ADJUSTR(globenv%default_dgemm_library(:40))
796 :
797 4598 : IF (globenv%diag_library == "ELPA") THEN
798 : WRITE (UNIT=output_unit, FMT="(T2,A,T71,I10)") &
799 4503 : start_section_label//"| Minimum number of eigenvectors for ELPA usage", &
800 9006 : globenv%elpa_neigvec_min
801 : END IF
802 :
803 4598 : IF (globenv%diag_library == "DLAF") THEN
804 : WRITE (UNIT=output_unit, FMT="(T2,A,T71,I10)") &
805 0 : start_section_label//"| Minimum number of eigenvectors for DLAF usage", &
806 0 : globenv%dlaf_neigvec_min
807 : END IF
808 :
809 : #if defined(__CHECK_DIAG)
810 : ! Perform default check if no threshold value has been specified explicitly
811 : IF (globenv%eps_check_diag < 0.0_dp) THEN
812 : WRITE (UNIT=output_unit, FMT="(T2,A,T71,ES10.3)") &
813 : start_section_label//"| Orthonormality check for eigenvectors enabled", &
814 : eps_check_diag_default
815 : ELSE
816 : WRITE (UNIT=output_unit, FMT="(T2,A,T71,ES10.3)") &
817 : start_section_label//"| Orthonormality check for eigenvectors enabled", &
818 : globenv%eps_check_diag
819 : END IF
820 : #else
821 4598 : IF (globenv%eps_check_diag < 0.0_dp) THEN
822 : WRITE (UNIT=output_unit, FMT="(T2,A,T73,A)") &
823 4594 : start_section_label//"| Orthonormality check for eigenvectors", &
824 9188 : "DISABLED"
825 : ELSE
826 : WRITE (UNIT=output_unit, FMT="(T2,A,T71,ES10.3)") &
827 4 : start_section_label//"| Orthonormality check for eigenvectors enabled", &
828 8 : globenv%eps_check_diag
829 : END IF
830 : #endif
831 4598 : CALL section_release(section)
832 :
833 0 : SELECT CASE (cp_fm_get_mm_type())
834 : CASE (do_scalapack)
835 : WRITE (UNIT=output_unit, FMT="(T2,A,T72,A)") &
836 0 : start_section_label//"| Matrix multiplication library", "ScaLAPACK"
837 : CASE (do_cosma)
838 : WRITE (UNIT=output_unit, FMT="(T2,A,T76,A)") &
839 4598 : start_section_label//"| Matrix multiplication library", "COSMA"
840 : END SELECT
841 :
842 4598 : CALL section_vals_val_get(global_section, "ALLTOALL_SGL", l_val=ata)
843 : WRITE (UNIT=output_unit, FMT="(T2,A,T80,L1)") &
844 4598 : start_section_label//"| All-to-all communication in single precision", ata
845 4598 : CALL section_vals_val_get(global_section, "EXTENDED_FFT_LENGTHS", l_val=efl)
846 : WRITE (UNIT=output_unit, FMT="(T2,A,T80,L1)") &
847 4598 : start_section_label//"| FFTs using library dependent lengths", efl
848 :
849 135 : SELECT CASE (print_level)
850 : CASE (silent_print_level)
851 135 : print_level_string = "SILENT"
852 : CASE (low_print_level)
853 1992 : print_level_string = " LOW"
854 : CASE (medium_print_level)
855 2420 : print_level_string = "MEDIUM"
856 : CASE (high_print_level)
857 26 : print_level_string = " HIGH"
858 : CASE (debug_print_level)
859 25 : print_level_string = " DEBUG"
860 : CASE DEFAULT
861 4598 : CPABORT("Unknown print_level")
862 : END SELECT
863 :
864 4598 : CALL section_vals_val_get(global_section, "GRID%BACKEND", i_val=i_grid_backend)
865 4588 : SELECT CASE (i_grid_backend)
866 : CASE (GRID_BACKEND_AUTO)
867 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,A6)") &
868 4588 : start_section_label//"| Grid backend", "AUTO"
869 : CASE (GRID_BACKEND_CPU)
870 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,A6)") &
871 4 : start_section_label//"| Grid backend", "CPU"
872 : CASE (GRID_BACKEND_DGEMM)
873 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,A6)") &
874 4 : start_section_label//"| Grid backend", "DGEMM"
875 : CASE (GRID_BACKEND_GPU)
876 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,A6)") &
877 0 : start_section_label//"| Grid backend", "GPU"
878 : CASE (GRID_BACKEND_HIP)
879 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,A6)") &
880 0 : start_section_label//"| Grid backend", "HIP"
881 : CASE (GRID_BACKEND_REF)
882 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,A6)") &
883 4598 : start_section_label//"| Grid backend", "REF"
884 : END SELECT
885 :
886 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,A6)") &
887 4598 : start_section_label//"| Global print level", print_level_string
888 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,L6)") &
889 4598 : start_section_label//"| MPI I/O enabled", flag
890 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,I6)") &
891 4598 : start_section_label//"| Total number of message passing processes", &
892 4598 : para_env%num_pe, &
893 4598 : start_section_label//"| Number of threads for this process", &
894 4598 : num_threads, &
895 9196 : start_section_label//"| This output is from process", para_env%mepos
896 :
897 4598 : CALL m_get_omp_stacksize(omp_stacksize)
898 : WRITE (UNIT=output_unit, FMT="(T2,A,T68,A13)") &
899 4598 : start_section_label//"| Stack size for threads created by OpenMP (OMP_STACKSIZE)", &
900 9196 : ADJUSTR(omp_stacksize)
901 :
902 4598 : CALL m_cpuinfo(model_name)
903 : WRITE (UNIT=output_unit, FMT="(T2,A,T30,A51)") &
904 4598 : start_section_label//"| CPU model name", ADJUSTR(TRIM(model_name))
905 :
906 4598 : cpuid = m_cpuid()
907 4598 : cpuid_static = m_cpuid_static()
908 :
909 4598 : IF ((cpuid > 0) .OR. (cpuid_static > 0)) THEN
910 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,I6)") &
911 4598 : start_section_label//"| CPUID", cpuid
912 4598 : IF (cpuid /= cpuid_static) THEN
913 : WRITE (UNIT=output_unit, FMT="(T2,A,T75,I6)") &
914 0 : start_section_label//"| Compiled for CPUID", cpuid_static
915 : END IF
916 : END IF
917 :
918 4598 : IF (cpuid_static < cpuid) THEN
919 : ! base/machine_cpuid.c relies on the (same) target flags as the Fortran code
920 : CALL cp_hint(__LOCATION__, "The compiler target flags ("// &
921 : TRIM(m_cpuid_name(cpuid_static))//") used to build this binary cannot exploit "// &
922 : "all extensions of this CPU model ("//TRIM(m_cpuid_name(cpuid))//"). "// &
923 0 : "Consider compiler target flags as part of FCFLAGS and CFLAGS (ARCH file).")
924 : END IF
925 :
926 4598 : WRITE (UNIT=output_unit, FMT="()")
927 4598 : WRITE (UNIT=output_unit, FMT="(T2,A)") "MEMORY| system memory details [Kb]"
928 4598 : WRITE (UNIT=output_unit, FMT="(T2,A23,4A14)") "MEMORY| ", "rank 0", "min", "max", "average"
929 4598 : WRITE (UNIT=output_unit, FMT="(T2,A23,4I14)") "MEMORY| MemTotal ", memtotal, memtotal_min, memtotal_max, memtotal_avr
930 4598 : WRITE (UNIT=output_unit, FMT="(T2,A23,4I14)") "MEMORY| MemFree ", memFree, memfree_min, memfree_max, memfree_avr
931 4598 : WRITE (UNIT=output_unit, FMT="(T2,A23,4I14)") "MEMORY| Buffers ", Buffers, Buffers_min, Buffers_max, Buffers_avr
932 4598 : WRITE (UNIT=output_unit, FMT="(T2,A23,4I14)") "MEMORY| Cached ", Cached, Cached_min, Cached_max, Cached_avr
933 4598 : WRITE (UNIT=output_unit, FMT="(T2,A23,4I14)") "MEMORY| Slab ", Slab, Slab_min, Slab_max, Slab_avr
934 : WRITE (UNIT=output_unit, FMT="(T2,A23,4I14)") &
935 4598 : "MEMORY| SReclaimable ", SReclaimable, SReclaimable_min, SReclaimable_max, &
936 9196 : SReclaimable_avr
937 : WRITE (UNIT=output_unit, FMT="(T2,A23,4I14)") &
938 4598 : "MEMORY| MemLikelyFree ", MemLikelyFree, MemLikelyFree_min, MemLikelyFree_max, &
939 9196 : MemLikelyFree_avr
940 4598 : WRITE (UNIT=output_unit, FMT='()')
941 :
942 : END IF
943 :
944 : CALL cp_print_key_finished_output(output_unit, logger, global_section, &
945 8989 : "PROGRAM_RUN_INFO")
946 :
947 8989 : END SUBROUTINE read_global_section
948 :
949 : ! **************************************************************************************************
950 : !> \brief ...
951 : !> \param root_section ...
952 : !> \param para_env ...
953 : !> \param globenv ...
954 : !> \par History
955 : !> 2-Dec-2000 (JGH) added default fft library
956 : !> \author JGH,MK
957 : ! **************************************************************************************************
958 8989 : SUBROUTINE read_cp2k_section(root_section, para_env, globenv)
959 :
960 : TYPE(section_vals_type), POINTER :: root_section
961 : TYPE(mp_para_env_type), POINTER :: para_env
962 : TYPE(global_environment_type), POINTER :: globenv
963 :
964 : INTEGER :: output_unit
965 : TYPE(cp_logger_type), POINTER :: logger
966 : TYPE(section_vals_type), POINTER :: global_section
967 :
968 8989 : global_section => section_vals_get_subs_vals(root_section, "GLOBAL")
969 8989 : CALL read_global_section(root_section, para_env, globenv)
970 8989 : logger => cp_get_default_logger()
971 : output_unit = cp_print_key_unit_nr(logger, global_section, "PROGRAM_RUN_INFO", &
972 8989 : extension=".log")
973 :
974 8989 : CALL fft_setup_library(globenv, global_section)
975 8989 : CALL diag_setup_library(globenv)
976 :
977 : CALL cp_print_key_finished_output(output_unit, logger, global_section, &
978 8989 : "PROGRAM_RUN_INFO")
979 :
980 8989 : END SUBROUTINE read_cp2k_section
981 :
982 : ! **************************************************************************************************
983 : !> \brief check FFT preferred library availability, if not switch
984 : !> \param globenv ...
985 : !> \param global_section ...
986 : !> \par History
987 : !> 2-Dec-2000 (JGH) added default fft library
988 : !> Nov-2013 (MI) refactoring
989 : !> \author JGH,MK
990 : ! **************************************************************************************************
991 8989 : SUBROUTINE fft_setup_library(globenv, global_section)
992 :
993 : TYPE(global_environment_type), POINTER :: globenv
994 : TYPE(section_vals_type), POINTER :: global_section
995 :
996 : CHARACTER(LEN=3*default_string_length) :: message
997 : COMPLEX(KIND=dp), DIMENSION(4, 4, 4) :: zz
998 : INTEGER :: stat
999 : INTEGER, DIMENSION(3) :: n
1000 : LOGICAL :: try_fftw
1001 :
1002 35956 : n(:) = 4
1003 8989 : zz(:, :, :) = 0.0_dp
1004 :
1005 : ! Setup the FFT library
1006 : ! If the user has specified PREFERRED_FFT_LIBRARY try that first (default FFTW3)
1007 : ! If that one is not available, try FFTW3 (unless it has been tried already)
1008 : ! If FFTW3 is not available use FFTSG
1009 :
1010 8989 : IF (globenv%default_fft_library == "FFTW3") THEN
1011 : try_fftw = .FALSE.
1012 : ELSE
1013 8 : try_fftw = .TRUE.
1014 : END IF
1015 :
1016 : ! Initialize FFT library with the user's preferred FFT library
1017 : CALL init_fft(fftlib=TRIM(globenv%default_fft_library), &
1018 : alltoall=section_get_lval(global_section, "ALLTOALL_SGL"), &
1019 : fftsg_sizes=.NOT. section_get_lval(global_section, "EXTENDED_FFT_LENGTHS"), &
1020 : pool_limit=globenv%fft_pool_scratch_limit, &
1021 : wisdom_file=globenv%fftw_wisdom_file_name, &
1022 8989 : plan_style=globenv%fftw_plan_type)
1023 :
1024 : ! Check for FFT library
1025 8989 : CALL fft3d(1, n, zz, status=stat)
1026 8989 : IF (stat /= 0) THEN
1027 0 : IF (try_fftw) THEN
1028 : message = "FFT library "//TRIM(globenv%default_fft_library)// &
1029 0 : " is not available. Trying FFT library FFTW3."
1030 0 : CPWARN(TRIM(message))
1031 0 : globenv%default_fft_library = "FFTW3"
1032 : CALL init_fft(fftlib=TRIM(globenv%default_fft_library), &
1033 : alltoall=section_get_lval(global_section, "ALLTOALL_SGL"), &
1034 : fftsg_sizes=.NOT. section_get_lval(global_section, "EXTENDED_FFT_LENGTHS"), &
1035 : pool_limit=globenv%fft_pool_scratch_limit, &
1036 : wisdom_file=globenv%fftw_wisdom_file_name, &
1037 0 : plan_style=globenv%fftw_plan_type)
1038 :
1039 0 : CALL fft3d(1, n, zz, status=stat)
1040 : END IF
1041 0 : IF (stat /= 0) THEN
1042 : message = "FFT library "//TRIM(globenv%default_fft_library)// &
1043 0 : " is not available. Trying FFT library FFTSG."
1044 0 : CPWARN(TRIM(message))
1045 0 : globenv%default_fft_library = "FFTSG"
1046 : CALL init_fft(fftlib=TRIM(globenv%default_fft_library), &
1047 : alltoall=section_get_lval(global_section, "ALLTOALL_SGL"), &
1048 : fftsg_sizes=.NOT. section_get_lval(global_section, "EXTENDED_FFT_LENGTHS"), &
1049 : pool_limit=globenv%fft_pool_scratch_limit, &
1050 : wisdom_file=globenv%fftw_wisdom_file_name, &
1051 0 : plan_style=globenv%fftw_plan_type)
1052 :
1053 0 : CALL fft3d(1, n, zz, status=stat)
1054 0 : IF (stat /= 0) THEN
1055 0 : CPABORT("FFT library FFTSG does not work. No FFT library available.")
1056 : END IF
1057 : END IF
1058 : END IF
1059 :
1060 8989 : END SUBROUTINE fft_setup_library
1061 :
1062 : ! **************************************************************************************************
1063 : !> \brief availability diagonalizatioon library
1064 : !>
1065 : !> \param globenv ...
1066 : !> \author MI
1067 : ! **************************************************************************************************
1068 8989 : SUBROUTINE diag_setup_library(globenv)
1069 : TYPE(global_environment_type), POINTER :: globenv
1070 :
1071 : CHARACTER(LEN=3*default_string_length) :: message
1072 : LOGICAL :: fallback_applied
1073 :
1074 : CALL diag_init(diag_lib=TRIM(globenv%diag_library), &
1075 : fallback_applied=fallback_applied, &
1076 : elpa_kernel=globenv%k_elpa, &
1077 : elpa_neigvec_min_input=globenv%elpa_neigvec_min, &
1078 : elpa_qr=globenv%elpa_qr, &
1079 : elpa_print=globenv%elpa_print, &
1080 : elpa_qr_unsafe=globenv%elpa_qr_unsafe, &
1081 : dlaf_neigvec_min_input=globenv%dlaf_neigvec_min, &
1082 8989 : eps_check_diag_input=globenv%eps_check_diag)
1083 :
1084 8989 : IF (fallback_applied) THEN
1085 : message = "Diagonalization library "//TRIM(globenv%diag_library)// &
1086 0 : " is not available. The ScaLAPACK library is used as fallback."
1087 0 : CPWARN(TRIM(message))
1088 : END IF
1089 :
1090 8989 : END SUBROUTINE diag_setup_library
1091 :
1092 : ! **************************************************************************************************
1093 : !> \brief ...
1094 : !> \param glob_section ...
1095 : ! **************************************************************************************************
1096 44945 : SUBROUTINE fm_setup(glob_section)
1097 : TYPE(section_vals_type), POINTER :: glob_section
1098 :
1099 : INTEGER :: multiplication_type, ncb, nrb
1100 : LOGICAL :: force_me
1101 : TYPE(section_vals_type), POINTER :: fm_section
1102 :
1103 8989 : fm_section => section_vals_get_subs_vals(glob_section, "FM")
1104 :
1105 8989 : CALL section_vals_val_get(fm_section, "NROW_BLOCKS", i_val=nrb)
1106 8989 : CALL section_vals_val_get(fm_section, "NCOL_BLOCKS", i_val=ncb)
1107 8989 : CALL section_vals_val_get(fm_section, "FORCE_BLOCK_SIZE", l_val=force_me)
1108 :
1109 8989 : CALL cp_fm_struct_config(nrow_block=nrb, ncol_block=ncb, force_block=force_me)
1110 :
1111 : CALL section_vals_val_get(fm_section, "TYPE_OF_MATRIX_MULTIPLICATION", &
1112 8989 : i_val=multiplication_type)
1113 :
1114 8989 : CALL cp_fm_setup(multiplication_type)
1115 :
1116 8989 : END SUBROUTINE fm_setup
1117 :
1118 : ! **************************************************************************************************
1119 : !> \brief ...
1120 : !> \param glob_section ...
1121 : ! **************************************************************************************************
1122 8989 : SUBROUTINE dgemm_setup(glob_section)
1123 : TYPE(section_vals_type), POINTER :: glob_section
1124 :
1125 : INTEGER :: dgemm_type
1126 :
1127 8989 : CALL section_vals_val_get(glob_section, "PREFERRED_DGEMM_LIBRARY", i_val=dgemm_type)
1128 :
1129 8989 : CALL local_gemm_set_library(dgemm_type)
1130 :
1131 8989 : END SUBROUTINE dgemm_setup
1132 :
1133 : ! **************************************************************************************************
1134 : !> \brief Parses the input section used to define the heuristic rules which determine if
1135 : !> a FM matrix should be redistributed before diagonalizing it.
1136 : !> \param glob_section the global input section
1137 : !> \author Nico Holmberg [01.2018]
1138 : ! **************************************************************************************************
1139 44945 : SUBROUTINE fm_diag_rules_setup(glob_section)
1140 : TYPE(section_vals_type), POINTER :: glob_section
1141 :
1142 : INTEGER :: a, x
1143 : LOGICAL :: elpa_force_redistribute, should_print
1144 : TYPE(section_vals_type), POINTER :: section
1145 :
1146 8989 : section => section_vals_get_subs_vals(glob_section, "FM_DIAG_SETTINGS")
1147 :
1148 8989 : CALL section_vals_val_get(section, "PARAMETER_A", i_val=a)
1149 8989 : CALL section_vals_val_get(section, "PARAMETER_X", i_val=x)
1150 8989 : CALL section_vals_val_get(section, "PRINT_FM_REDISTRIBUTE", l_val=should_print)
1151 8989 : CALL section_vals_val_get(section, "ELPA_FORCE_REDISTRIBUTE", l_val=elpa_force_redistribute)
1152 :
1153 8989 : CALL cp_fm_redistribute_init(a, x, should_print, elpa_force_redistribute)
1154 :
1155 8989 : END SUBROUTINE fm_diag_rules_setup
1156 : ! **************************************************************************************************
1157 : !> \brief reads the Walltime also in format HH:MM:SS
1158 : !> \param section ...
1159 : !> \param keyword_name ...
1160 : !> \param walltime ...
1161 : !> \par History
1162 : !> none
1163 : !> \author Mandes
1164 : ! **************************************************************************************************
1165 9009 : SUBROUTINE cp2k_get_walltime(section, keyword_name, walltime)
1166 : TYPE(section_vals_type), POINTER :: section
1167 : CHARACTER(len=*), INTENT(in) :: keyword_name
1168 : REAL(KIND=dp), INTENT(out) :: walltime
1169 :
1170 : CHARACTER(LEN=1) :: c1, c2
1171 : CHARACTER(LEN=100) :: txt
1172 : INTEGER :: hours, ierr, minutes, n, seconds
1173 :
1174 9009 : CALL section_vals_val_get(section, keyword_name, c_val=txt)
1175 9009 : n = LEN_TRIM(txt)
1176 :
1177 9009 : IF (n == 0) THEN
1178 8768 : walltime = -1.0_dp
1179 241 : ELSE IF (INDEX(txt, ":") == 0) THEN
1180 189 : READ (txt(1:n), FMT=*, IOSTAT=ierr) walltime
1181 189 : IF (ierr /= 0) CPABORT('Could not parse WALLTIME: "'//txt(1:n)//'"')
1182 : ELSE
1183 52 : READ (txt(1:n), FMT="(I2,A1,I2,A1,I2)", IOSTAT=ierr) hours, c1, minutes, c2, seconds
1184 52 : IF (n /= 8 .OR. ierr /= 0 .OR. c1 .NE. ":" .OR. c2 .NE. ":") &
1185 0 : CPABORT('Could not parse WALLTIME: "'//txt(1:n)//'"')
1186 52 : walltime = 3600.0_dp*REAL(hours, dp) + 60.0_dp*REAL(minutes, dp) + REAL(seconds, dp)
1187 : END IF
1188 9009 : END SUBROUTINE cp2k_get_walltime
1189 :
1190 : ! **************************************************************************************************
1191 : !> \brief Writes final timings and banner for CP2K
1192 : !> \param root_section ...
1193 : !> \param para_env ...
1194 : !> \param globenv ...
1195 : !> \param wdir ...
1196 : !> \param q_finalize ...
1197 : !> \par History
1198 : !> none
1199 : !> \author JGH,MK
1200 : !> \note
1201 : !> The following routines need to be synchronized wrt. adding/removing
1202 : !> of the default environments (logging, performance,error):
1203 : !> environment:cp2k_init, environment:cp2k_finalize,
1204 : !> f77_interface:f_env_add_defaults, f77_interface:f_env_rm_defaults,
1205 : !> f77_interface:create_force_env, f77_interface:destroy_force_env
1206 : ! **************************************************************************************************
1207 17978 : SUBROUTINE cp2k_finalize(root_section, para_env, globenv, wdir, q_finalize)
1208 :
1209 : TYPE(section_vals_type), POINTER :: root_section
1210 : TYPE(mp_para_env_type), POINTER :: para_env
1211 : TYPE(global_environment_type), POINTER :: globenv
1212 : CHARACTER(LEN=*), OPTIONAL :: wdir
1213 : LOGICAL, INTENT(IN), OPTIONAL :: q_finalize
1214 :
1215 : CHARACTER(LEN=default_path_length) :: cg_filename
1216 : INTEGER :: cg_mode, iw, unit_exit
1217 : LOGICAL :: delete_it, do_finalize, report_maxloc, &
1218 : sort_by_self_time
1219 : REAL(KIND=dp) :: r_timings
1220 : TYPE(cp_logger_type), POINTER :: logger
1221 :
1222 : ! Look if we inherited a failure, more care is needed if so
1223 : ! i.e. the input is most likely not available
1224 : ! Set flag if this is a development version
1225 :
1226 8989 : do_finalize = .TRUE.
1227 8989 : IF (PRESENT(q_finalize)) do_finalize = q_finalize
1228 : ! Clean up
1229 8989 : NULLIFY (logger)
1230 8989 : logger => cp_get_default_logger()
1231 8989 : IF (do_finalize) THEN
1232 8779 : CALL deallocate_spherical_harmonics()
1233 8779 : CALL deallocate_orbital_pointers()
1234 8779 : CALL deallocate_md_ftable()
1235 8779 : CALL diag_finalize()
1236 : ! finalize the fft (i.e. writes the wisdom if FFTW3 )
1237 8779 : CALL finalize_fft(para_env, globenv%fftw_wisdom_file_name)
1238 8779 : CALL finalize_libvori()
1239 : END IF
1240 :
1241 : ! Write message passing performance info
1242 :
1243 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PROGRAM_RUN_INFO", &
1244 8989 : extension=".log")
1245 8989 : CALL describe_mp_perf_env(iw)
1246 : CALL cp_print_key_finished_output(iw, logger, root_section, &
1247 8989 : "GLOBAL%PROGRAM_RUN_INFO")
1248 :
1249 8989 : CALL collect_citations_from_ranks(para_env)
1250 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%REFERENCES", &
1251 8989 : extension=".Log")
1252 8989 : IF (iw > 0) THEN
1253 4590 : WRITE (UNIT=iw, FMT="(/,T2,A)") REPEAT("-", 79)
1254 4590 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
1255 4590 : WRITE (UNIT=iw, FMT="(T2,A,T30,A,T80,A)") "-", "R E F E R E N C E S", "-"
1256 4590 : WRITE (UNIT=iw, FMT="(T2,A,T80,A)") "-", "-"
1257 4590 : WRITE (UNIT=iw, FMT="(T2,A)") REPEAT("-", 79)
1258 :
1259 4590 : WRITE (UNIT=iw, FMT="(T2,A)") ""
1260 4590 : WRITE (UNIT=iw, FMT="(T2,A)") TRIM(cp2k_version)//", the CP2K developers group ("//TRIM(cp2k_year)//")."
1261 4590 : WRITE (UNIT=iw, FMT="(T2,A)") "CP2K is freely available from "//TRIM(cp2k_home)//" ."
1262 :
1263 : CALL print_all_references(sorted=.TRUE., cited_only=.TRUE., &
1264 4590 : FORMAT=print_format_journal, unit=iw)
1265 : END IF
1266 : CALL cp_print_key_finished_output(iw, logger, root_section, &
1267 8989 : "GLOBAL%REFERENCES")
1268 :
1269 8989 : CALL timestop(globenv%handle) ! corresponding the "CP2K" in cp2k_init
1270 :
1271 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%TIMINGS", &
1272 8989 : extension=".Log")
1273 8989 : r_timings = section_get_rval(root_section, "GLOBAL%TIMINGS%THRESHOLD")
1274 8989 : sort_by_self_time = section_get_lval(root_section, "GLOBAL%TIMINGS%SORT_BY_SELF_TIME")
1275 8989 : report_maxloc = section_get_lval(root_section, "GLOBAL%TIMINGS%REPORT_MAXLOC")
1276 8989 : IF (m_energy() .NE. 0.0_dp) THEN
1277 0 : CALL timings_report_print(iw, r_timings, sort_by_self_time, cost_type_energy, report_maxloc, para_env)
1278 : END IF
1279 8989 : CALL timings_report_print(iw, r_timings, sort_by_self_time, cost_type_time, report_maxloc, para_env)
1280 :
1281 : ! Write the callgraph, if desired by user
1282 8989 : CALL section_vals_val_get(root_section, "GLOBAL%CALLGRAPH", i_val=cg_mode)
1283 8989 : IF (cg_mode /= CALLGRAPH_NONE) THEN
1284 2 : CALL section_vals_val_get(root_section, "GLOBAL%CALLGRAPH_FILE_NAME", c_val=cg_filename)
1285 2 : IF (LEN_TRIM(cg_filename) == 0) cg_filename = TRIM(logger%iter_info%project_name)
1286 2 : IF (cg_mode == CALLGRAPH_ALL) & !incorporate mpi-rank into filename
1287 0 : cg_filename = TRIM(cg_filename)//"_"//TRIM(ADJUSTL(cp_to_string(para_env%mepos)))
1288 2 : IF (iw > 0) THEN
1289 1 : WRITE (UNIT=iw, FMT="(T2,3X,A)") "Writing callgraph to: "//TRIM(cg_filename)//".callgraph"
1290 1 : WRITE (UNIT=iw, FMT="()")
1291 1 : WRITE (UNIT=iw, FMT="(T2,A)") "-------------------------------------------------------------------------------"
1292 : END IF
1293 2 : IF (cg_mode == CALLGRAPH_ALL .OR. para_env%is_source()) &
1294 1 : CALL timings_report_callgraph(TRIM(cg_filename)//".callgraph")
1295 : END IF
1296 :
1297 : CALL cp_print_key_finished_output(iw, logger, root_section, &
1298 8989 : "GLOBAL%TIMINGS")
1299 :
1300 8989 : CALL rm_mp_perf_env()
1301 8989 : CALL rm_timer_env()
1302 :
1303 8989 : IF (para_env%is_source()) THEN
1304 : iw = cp_print_key_unit_nr(logger, root_section, "GLOBAL%PROGRAM_RUN_INFO", &
1305 4598 : extension=".log")
1306 :
1307 : ! Deleting (if existing) the external EXIT files
1308 4598 : delete_it = .FALSE.
1309 4598 : INQUIRE (FILE="EXIT", EXIST=delete_it)
1310 4598 : IF (delete_it) THEN
1311 0 : CALL open_file(file_name="EXIT", unit_number=unit_exit)
1312 0 : CALL close_file(unit_number=unit_exit, file_status="DELETE")
1313 : END IF
1314 :
1315 4598 : delete_it = .FALSE.
1316 4598 : INQUIRE (FILE=TRIM(logger%iter_info%project_name)//".EXIT", EXIST=delete_it)
1317 4598 : IF (delete_it) THEN
1318 0 : CALL open_file(file_name=TRIM(logger%iter_info%project_name)//".EXIT", unit_number=unit_exit)
1319 0 : CALL close_file(unit_number=unit_exit, file_status="DELETE")
1320 : END IF
1321 :
1322 : ! Print warning counter
1323 4598 : IF (iw > 0) THEN
1324 4598 : WRITE (iw, "(T2,A,I0)") "The number of warnings for this run is : ", warning_counter
1325 4598 : WRITE (iw, *) ""
1326 4598 : WRITE (UNIT=iw, FMT="(T2,A)") REPEAT("-", 79)
1327 : END IF
1328 :
1329 : ! Update the runtime environment variables
1330 4598 : CALL get_runtime_info()
1331 :
1332 : ! Just a choice, do not print the CP2K footer if there is a failure
1333 5118 : CALL cp2k_footer(iw, wdir)
1334 4598 : IF (iw > 0) FLUSH (iw) ! ignore &GLOBAL / FLUSH_SHOULD_FLUSH
1335 :
1336 : CALL cp_print_key_finished_output(iw, logger, root_section, &
1337 4598 : "GLOBAL%PROGRAM_RUN_INFO")
1338 : END IF
1339 :
1340 : ! Release message passing environment
1341 8989 : CALL cp_rm_default_logger()
1342 :
1343 8989 : END SUBROUTINE cp2k_finalize
1344 :
1345 : END MODULE environment
|