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