Line data Source code
1 : !!****p* ABINIT/abinit
2 : !! NAME
3 : !! abinit
4 : !!
5 : !! FUNCTION
6 : !! Main routine for conducting Density-Functional Theory calculations or Many-Body Perturbation Theory calculations.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, MKV, MT)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
14 : !!
15 : !! NOTES
16 : !! The new user is strongly adviced to read the
17 : !! latest version of the file ~abinit/doc/users/new_user_guide.html
18 : !! before trying to modify or even use the code.
19 : !! Even experienced users of the code should also be careful in coding,
20 : !! please read the latest version of the file ~abinit/doc/developers/rules_coding
21 : !!
22 : !! The present main routine drives the following operations :
23 : !!
24 : !! 1) Eventually initialize MPI
25 : !! 2) Initialize overall timing of run
26 : !! 3) Print greeting for interactive user and
27 : !! Read names of files (input, output, rootinput, rootoutput, roottemporaries),
28 : !! create the name of the status file, initialize the status subroutine.
29 : !! 4) Open output file and print herald at top of output and log files
30 : !! 5) Read the input file, and store the information in a long string of characters
31 : !! 6) Take ndtset from the input string, then allocate
32 : !! the arrays whose dimensions depends only on ndtset
33 : !! 7) Continue to analyze the input string, and allocate the remaining arrays.
34 : !! Also modulate the timing according to timopt.
35 : !! 8) Finish to read the "file" file completely,
36 : !! and also initialize pspheads (the pseudopotential header information)
37 : !! 9) Provide defaults for the variables that have not yet been initialized.
38 : !! 10) Perform some global initialization, depending on the value of
39 : !! pseudopotentials, parallelism variables, or macro input variables
40 : !! 11) Call the main input routine.
41 : !! 12) Echo input data to output file and log file
42 : !! 13) Perform additional checks on input data
43 : !! At this stage, all the information from the "files" file and "input" file
44 : !! have been read and checked.
45 : !! 14) Print more information, and activate GPU
46 : !! ___________________________________________
47 : !! 15) Perform main calculation (call driver)
48 : !! -------------------------------------------
49 : !!
50 : !! 16) Give final echo of coordinates, etc.
51 : !! 17) Timing analysis
52 : !! 18) Bibliographical recommendations
53 : !! 19) Delete the status file, and, for build-in tests, analyse the correctness of results
54 : !! 20) Write the final timing, close the output file, and write a final line to the log file
55 : !! 21) Eventual cleaning of MPI run
56 : !!
57 : !! INPUTS
58 : !! (main routine)
59 : !!
60 : !! OUTPUT
61 : !! (main routine)
62 : !!
63 : !! SOURCE
64 :
65 : #if defined HAVE_CONFIG_H
66 : #include "config.h"
67 : #endif
68 :
69 : #include "abi_common.h"
70 : #include "nvtx_macros.h"
71 :
72 2886 : program abinit
73 :
74 2886 : use defs_basis
75 : use m_cppopts_dumper
76 : use m_optim_dumper
77 : use m_abicore
78 : use m_dtset
79 : use m_results_out
80 : use m_xmpi
81 : use m_xomp
82 : use m_xpapi
83 : use m_errors
84 : use m_argparse
85 : use m_nctk
86 : USE_MPI
87 :
88 : use defs_datatypes,only : pspheader_type
89 : use defs_abitypes, only : MPI_type
90 : use m_build_info, only : abinit_version, dump_config
91 : use m_parser, only : ab_dimensions
92 : use m_time , only : asctime, sec2str, timein, time_set_papiopt, timab
93 : use m_fstrings, only : sjoin, strcat, itoa, yesno, ljust
94 : use m_io_tools, only : flush_unit, delete_file
95 : use m_specialmsg, only : specialmsg_getcount, herald
96 : use m_exit, only : get_timelimit_string
97 : use m_atomdata, only : znucl2symbol
98 : use m_libpaw_tools,only : libpaw_spmsg_getcount
99 : use m_mpinfo, only : destroy_mpi_enreg, clnmpi_img, clnmpi_grid, clnmpi_atom, clnmpi_pert
100 : use m_memeval, only : memory_eval
101 : use m_chkinp, only : chkinp
102 : use m_dtfil, only : iofn1
103 : use m_outxml, only : outxml_open, outxml_finalise
104 : use m_out_acknowl, only : out_acknowl
105 : use m_timana, only : timana
106 : use m_builtin_tests, only : testfi
107 : use m_mpi_setup, only : mpi_setup
108 : use m_outvars, only : outvars
109 : use m_out_spg_anal, only : out_spg_anal
110 : use m_driver, only : driver
111 : use m_common, only : get_dtsets_pspheads
112 : use m_pstat, only : pstat_proc
113 :
114 : #ifdef HAVE_GPU
115 : use m_gpu_toolbox
116 : #endif
117 :
118 : #ifdef HAVE_GPU_CUDA
119 : use m_manage_cuda
120 : #endif
121 :
122 : #if defined(HAVE_GPU_MARKERS)
123 : use m_nvtx_data
124 : #endif
125 :
126 : #if defined HAVE_BIGDFT
127 : use BigDFT_API, only : bigdft_init_errors,bigdft_init_timing_categories,&
128 : & f_timing_initialize,f_timing_reset,wvl_timing => timing
129 : #endif
130 :
131 : implicit none
132 :
133 : #if defined HAVE_MPI1
134 : include 'mpif.h'
135 : #endif
136 :
137 : !Arguments -----------------------------------
138 : !Local variables-------------------------------
139 : !
140 : !===============================================================================
141 : ! abinit_version designate overall code version
142 : ! mpw=maximum number of planewaves in basis sphere
143 : ! unit numbers (ab_in,ab_out,std_out,tmp_unit) have been defined in defs_basis.f .
144 : ! The array filnam is used for the name of input and output files,
145 : ! and roots for generic input, output or temporary files.
146 : ! Pseudopotential file names are set in iofn2, and are contained in pspheads.
147 : ! The name filstat will be needed beyond gstate to check
148 : ! the appearance of the "exit" flag, to make a hasty exit, as well as
149 : ! in order to output the status of the computation.
150 : !==============================================================================
151 : ! Declarations
152 : ! Define "level of the routine", for debugging purposes
153 : integer,parameter :: level=1
154 : integer :: choice,dmatpuflag,ierr,ii,iounit,ios
155 : integer :: lenstr,me,print_mem_report
156 : integer :: mu,natom,ncomment,ncomment_paw,ndtset
157 : integer :: ndtset_alloc,nexit,nexit_paw,nfft,nkpt,npsp
158 : integer :: nsppol,nwarning,nwarning_paw,prtvol,timopt,gpu_option
159 2886 : integer,allocatable :: nband(:),npwtot(:)
160 : real(dp) :: etotal, tcpui, twalli
161 : real(dp) :: strten(6),tsec(2)
162 2886 : real(dp),allocatable :: gred(:,:),xred(:,:)
163 : character(len=24) :: codename
164 : character(len=24) :: start_datetime
165 : character(len=5000) :: msg
166 : character(len=strlen) :: string
167 : character(len=fnlen) :: filstat, filnam(5)
168 : type(args_t) :: args
169 2886 : type(dataset_type),allocatable :: dtsets(:)
170 2886 : type(MPI_type),allocatable :: mpi_enregs(:)
171 2886 : type(pspheader_type),allocatable :: pspheads(:)
172 2886 : type(results_out_type),allocatable,target :: results_out(:)
173 2886 : type(results_out_type),pointer :: results_out_all(:)
174 : type(ab_dimensions) :: mx
175 : logical :: test_img,test_exit,use_results_all,xml_output=.false.
176 : integer :: values(8)
177 : character(len=5) :: strzone
178 : character(len=8) :: strdat
179 : character(len=10) :: strtime
180 : character(len=13) :: warn_fmt
181 : integer :: gpu_devices(12)
182 : #ifdef HAVE_GPU
183 : integer :: lib_vers(2)
184 : #endif
185 : !******************************************************************
186 :
187 : !0) Change communicator for I/O (mandatory!)
188 2886 : call abi_io_redirect(new_io_comm=xmpi_world)
189 :
190 : !------------------------------------------------------------------------------
191 :
192 : !1) Eventually initialize MPI. Pay attention: me and comm may be initialzed again in finddistrproc
193 2886 : call xmpi_init()
194 2886 : me = xmpi_comm_rank(xmpi_world)
195 :
196 : ! Parse command line arguments.
197 2886 : args = args_parser(); if (args%exit /= 0) goto 100
198 :
199 : ! Initialize memory profiling if activated at configure time.
200 : ! if a full report is desired, set the argument of abimem_init to "2" instead of "0" via the command line.
201 : ! note that the file can easily be multiple GB in size so don't use this option normally
202 : #ifdef HAVE_MEM_PROFILING
203 : call abimem_init(args%abimem_level, limit_mb=args%abimem_limit_mb)
204 : #endif
205 :
206 : !------------------------------------------------------------------------------
207 :
208 : ! 2) Initialize overall timing of run:
209 2884 : call xpapi_init()
210 2884 : call xpapi_show_info(unit=std_out,mode_paral="COLL")
211 :
212 2884 : start_datetime = asctime()
213 2884 : call timein(tcpui,twalli)
214 2884 : call timab(1,0,tsec)
215 :
216 : ! Start to accumulate time for the entire run. The end of accumulation is in timana.f
217 2884 : call timab(1,1,tsec)
218 :
219 : !------------------------------------------------------------------------------
220 :
221 : !3) Print greeting for interactive user,
222 : !read names of files (input, output, rootinput, rootoutput, roottemporaries),
223 : !create the name of the status file, initialize the status subroutine.
224 :
225 2884 : call timab(101,3,tsec)
226 2884 : call iofn1(args%input_path, filnam, filstat, xmpi_world)
227 :
228 : !------------------------------------------------------------------------------
229 :
230 : !4) Open output file and print herald at top of output and log files
231 :
232 2884 : if (me==0) then
233 : #ifdef FC_NAG
234 : open(unit=ab_out,file=filnam(2),form='formatted',status='new', action="write", recl=ABI_RECL, iomsg=msg, iostat=ios)
235 : #else
236 2328 : open(unit=ab_out,file=filnam(2),form='formatted',status='new', action="write", iomsg=msg, iostat=ios)
237 : #endif
238 2328 : ABI_CHECK(ios == 0, msg)
239 : ! rewind (unit=ab_out)
240 2328 : codename='ABINIT'//repeat(' ',18)
241 2328 : call herald(codename,abinit_version,ab_out)
242 2328 : call herald(codename,abinit_version,std_out)
243 2328 : call dump_config(std_out)
244 2328 : call dump_optim(std_out)
245 2328 : call dump_cpp_options(std_out)
246 : ! Write names of files
247 : write(msg, '(a,a,a,a,a,a,a,a,a,a,a,a)' )&
248 2328 : '- input file -> ',trim(filnam(1)),ch10,&
249 2328 : '- output file -> ',trim(filnam(2)),ch10,&
250 2328 : '- root for input files -> ',trim(filnam(3)),ch10,&
251 4656 : '- root for output files -> ',trim(filnam(4)),ch10
252 6984 : call wrtout([std_out, ab_out], msg)
253 : end if
254 : !call wrtout(std_out, ' abinit : after writing the name of files ','PERS')
255 :
256 : ! Test if the netcdf library supports MPI-IO
257 2884 : call nctk_test_mpiio()
258 :
259 2884 : call timab(101,2,tsec)
260 :
261 : call get_dtsets_pspheads(args%input_path, filnam(1), ndtset, lenstr, string, &
262 2884 : timopt, dtsets, pspheads, mx, dmatpuflag, xmpi_world)
263 :
264 2856 : call timab(103,1,tsec)
265 :
266 2856 : ndtset_alloc = size(dtsets) - 1
267 2856 : npsp = size(pspheads)
268 :
269 : #if defined HAVE_BIGDFT
270 : call f_lib_initialize()
271 : call bigdft_init_errors()
272 : call bigdft_init_timing_categories()
273 : if (timopt==10) then
274 : call delete_file('wvl_timings.yaml',ierr)
275 : call f_timing_reset(filename='wvl_time.yaml',master=me==0,verbose_mode=.false.)
276 : end if
277 : #endif
278 :
279 19630 : ABI_MALLOC(mpi_enregs, (0:max(1,ndtset)))
280 2856 : call mpi_setup(dtsets,filnam,lenstr,mpi_enregs,ndtset,ndtset_alloc,string)
281 :
282 2854 : call memory_eval(dtsets,ab_out,mpi_enregs,ndtset,ndtset_alloc,npsp,pspheads)
283 :
284 : !------------------------------------------------------------------------------
285 :
286 : !12) Echo input data to output file and log file
287 :
288 : ! For evolving variables, and results
289 2854 : ABI_MALLOC(results_out, (0:ndtset_alloc))
290 :
291 : ! Initialize results_out datastructure
292 2854 : call init_results_out(dtsets,1,1,mpi_enregs, mx%natom, mx%mband_upper, mx%nkpt,npsp, mx%nsppol, mx%ntypat, results_out)
293 :
294 : ! Gather contributions to results_out from images of the cell, if needed
295 19624 : test_img = (mx%nimage/=1.and.maxval(dtsets(:)%npimage)>1)
296 2854 : use_results_all=.false.
297 2854 : if (test_img) then
298 0 : use_results_all=(me==0)
299 0 : if (use_results_all) then
300 0 : ABI_MALLOC(results_out_all, (0:ndtset_alloc))
301 : end if
302 :
303 0 : call gather_results_out(dtsets,mpi_enregs,results_out,results_out_all,use_results_all, allgather=.false.,master=0)
304 :
305 : else
306 2854 : results_out_all => results_out
307 : end if
308 :
309 2854 : if (me == 0) then
310 : ! Echo input to output file on unit ab_out, and to log file on unit 06 :
311 2298 : choice=1
312 6894 : do ii=1,2
313 4596 : if(ii==1)iounit=ab_out
314 4596 : if(ii==2)iounit=std_out
315 :
316 6894 : call outvars(choice,dmatpuflag,dtsets, filnam(4), iounit, mx, ndtset,ndtset_alloc,npsp,results_out_all,timopt)
317 : end do
318 :
319 2298 : if (dtsets(1)%prtxml == 1) then
320 2 : call outxml_open(trim(filnam(4)))
321 2 : call date_and_time(strdat,strtime,strzone,values)
322 2 : xml_output = .true.
323 : else
324 2296 : xml_output = .false.
325 : end if
326 :
327 : end if ! me==0
328 :
329 : ! Clean memory
330 2854 : if (test_img.and.me==0) then
331 0 : call destroy_results_out(results_out_all)
332 0 : ABI_FREE(results_out_all)
333 : end if
334 :
335 : !This synchronization is not strictly needed, but without it,
336 : !there are problems with Tv1#93 in parallel, PGI compiler, on Intel/PC
337 2854 : call abi_io_redirect(new_io_comm=xmpi_world)
338 :
339 2854 : call timab(103,2,tsec)
340 2854 : call timab(104,3,tsec)
341 :
342 : !------------------------------------------------------------------------------
343 :
344 : ! 13) Perform additional checks on input data
345 :
346 2854 : call chkinp(dtsets, ab_out, mpi_enregs, ndtset, ndtset_alloc, npsp, pspheads, xmpi_world)
347 :
348 : ! Check whether the string only contains valid keywords
349 2854 : call chkvars(string)
350 :
351 : ! At this stage, all the information from the "files" file and "input" file have been read and checked.
352 :
353 : !------------------------------------------------------------------------------
354 :
355 : !14) Print more information, and activate GPU
356 :
357 2854 : if (me == 0) then
358 2298 : call print_kinds(std_out) ! Printout of kinds and precisions.
359 2298 : call xomp_show_info(std_out) ! Info on the openMP environment.
360 2298 : call xmpi_show_info(std_out) ! Info on the MPI environment.
361 : end if
362 :
363 : !Activate GPU is required
364 2854 : gpu_option=ABI_GPU_DISABLED
365 37102 : gpu_devices(:)=-1
366 16770 : do ii=1,ndtset_alloc
367 16770 : if (dtsets(ii)%gpu_option/=ABI_GPU_DISABLED) then
368 0 : gpu_option=dtsets(ii)%gpu_option
369 0 : gpu_devices(:)=dtsets(ii)%gpu_devices(:)
370 : end if
371 : end do
372 : #ifdef HAVE_GPU
373 : call setdevice_cuda(gpu_devices,gpu_option)
374 : lib_vers(1) = gpu_get_lib_version_major()
375 : lib_vers(2) = gpu_get_lib_version_minor()
376 : if(gpu_option/=ABI_GPU_DISABLED) then
377 : #ifdef HAVE_GPU_CUDA
378 : write(std_out,'(a,i2,a,i1)') ' Using CUDA version: ',lib_vers(1),'.',lib_vers(2)
379 : #endif
380 : #ifdef HAVE_GPU_HIP
381 : write(std_out,'(a,i1,a,i1)') ' Using ROCm/HIP version: ',lib_vers(1),'.',lib_vers(2)
382 : #endif
383 : end if
384 :
385 : #else
386 2854 : if (gpu_option/=ABI_GPU_DISABLED) then
387 0 : write(msg,'(a)')ch10,'Use of GPU is requested but ABINIT was not built with GPU support.'
388 0 : ABI_ERROR(msg)
389 : end if
390 : #endif
391 :
392 : !Enable GPU markers (NVTX/ROCTX) if required
393 : #if defined(HAVE_GPU_MARKERS)
394 : NVTX_INIT()
395 : #endif
396 :
397 : !------------------------------------------------------------------------------
398 :
399 : !15) Perform main calculation
400 2854 : call timab(104,2,tsec)
401 :
402 2854 : test_exit=.false.
403 2854 : prtvol=dtsets(1)%prtvol
404 2854 : if (prtvol == -level .or. prtvol == -2 .or. args%dry_run /= 0) then
405 70 : write(msg,'(a,a,i0,a)')ch10,' abinit : before driver, prtvol=',prtvol,', debugging mode => will skip driver '
406 210 : call wrtout([std_out, ab_out], msg)
407 70 : test_exit=.true.
408 : end if
409 :
410 2854 : if(.not.test_exit)then
411 : ABI_NVTX_START_RANGE(NVTX_MAIN_COMPUTATION)
412 2784 : call driver(abinit_version,tcpui,dtsets,filnam,filstat, mpi_enregs,ndtset,ndtset_alloc,npsp,pspheads,results_out)
413 : ABI_NVTX_END_RANGE()
414 : end if
415 :
416 : !------------------------------------------------------------------------------
417 :
418 : ! 16) Give final echo of coordinates, etc.
419 2852 : call timab(105,1,tsec)
420 :
421 407836 : write(msg,'(a,a,a,62a,80a)') ch10,'== END DATASET(S) ',('=',mu=1,62),ch10,('=',mu=1,80)
422 8556 : call wrtout([std_out, ab_out], msg)
423 :
424 : ! Gather contributions to results_out from images of the cell, if needed
425 2852 : if (test_img) then
426 0 : if (use_results_all) then
427 0 : ABI_MALLOC(results_out_all,(0:ndtset_alloc))
428 : end if
429 :
430 0 : call gather_results_out(dtsets,mpi_enregs,results_out,results_out_all,use_results_all,allgather=.false.,master=0)
431 : end if
432 :
433 2852 : if(me==0) then
434 2296 : if(test_exit)then
435 70 : write(msg,'(a,a,i0,a)')ch10,' abinit : before driver, prtvol=',prtvol,', debugging mode => will skip outvars '
436 210 : call wrtout([std_out, ab_out], msg)
437 : else
438 : ! Echo input to output file on unit ab_out, and to log file on unit std_out.
439 : ! (Well, this might make sense for outvars, but not so much for out_spg_anal
440 : ! so there is only one call to the latter, for both units)
441 : ! both
442 2226 : choice=2
443 6678 : do ii=1,2
444 4452 : if(ii==1)iounit=ab_out
445 4452 : if(ii==2)iounit=std_out
446 4452 : write(iounit,*)' '
447 4452 : call outvars (choice,dmatpuflag,dtsets, filnam(4), iounit,mx,ndtset,ndtset_alloc,npsp,results_out_all,timopt)
448 4452 : if(ii==2)call out_spg_anal (dtsets,(ii-1),ab_out,ndtset,ndtset_alloc,results_out_all)
449 6678 : if(ii==2)write(std_out,*)' '
450 : end do
451 : end if
452 : end if ! me==0
453 :
454 : ! Clean memory
455 2852 : if (test_img.and.me==0) then
456 0 : call destroy_results_out(results_out_all)
457 0 : ABI_FREE(results_out_all)
458 : else
459 2852 : nullify(results_out_all)
460 : end if
461 :
462 : ! In prevision of the next two calls, some variables need to be transfered.
463 : ! They concern the case ndtset<2, and nimage=1 so take first value.
464 2852 : natom=dtsets(1)%natom ; nkpt=dtsets(1)%nkpt ; nsppol=dtsets(1)%nsppol
465 2852 : nfft=dtsets(1)%nfft
466 :
467 2852 : ABI_MALLOC(nband,(nkpt*nsppol))
468 2852 : ABI_MALLOC(npwtot,(nkpt))
469 2852 : ABI_MALLOC(gred,(3,natom))
470 2852 : ABI_MALLOC(xred,(3,natom))
471 :
472 2852 : etotal=results_out(1)%etotal(1)
473 39860 : gred(:,:) =results_out(1)%gred(:,1:natom,1)
474 57010 : nband(:) =dtsets(1)%nband(1:nkpt*nsppol)
475 54870 : npwtot(:) =results_out(1)%npwtot(1:nkpt,1)
476 19964 : strten(:) =results_out(1)%strten(:,1)
477 39860 : xred(:,:) =results_out(1)%xred(:,1:natom,1)
478 :
479 2852 : call timab(105,2,tsec)
480 :
481 : !------------------------------------------------------------------------------
482 :
483 : ! 17) Timing analysis
484 2852 : if(mod(timopt,10)/=0)then
485 252 : call timana (mpi_enregs(1), natom, nband, ndtset, nfft, nkpt, npwtot, nsppol, timopt)
486 : else
487 : #if defined HAVE_MPI
488 2600 : if(me==0)then ! This is for the automatic tests
489 2170 : write(ab_out,'(5a)')ch10,ch10,'- Timing analysis has been suppressed with timopt=0',ch10,ch10
490 : end if
491 : #endif
492 : end if
493 :
494 : !------------------------------------------------------------------------------
495 :
496 : ! 18) Bibliographical recommendations
497 2852 : if (me == 0) then
498 2296 : if (test_exit) then
499 70 : write(msg,'(a,a,i0,a)')ch10,' abinit : before driver, prtvol=',prtvol,', debugging mode => will skip acknowledgments'
500 210 : call wrtout([std_out, ab_out], msg)
501 : else
502 2226 : call out_acknowl(dtsets, ab_out, ndtset_alloc, npsp, pspheads)
503 : end if
504 : end if
505 :
506 : !------------------------------------------------------------------------------
507 :
508 : ! 19) Delete the status file, and, for build-in tests, analyse the correctness of results.
509 2852 : if (ndtset == 0 .and. me == 0 .and. dtsets(1)%builtintest /= 0) then
510 24 : call testfi(dtsets(1)%builtintest,etotal,filstat,gred,natom,strten,xred)
511 : end if
512 :
513 : ! One should have here the explicit deallocation of all arrays
514 2852 : call destroy_results_out(results_out)
515 :
516 2852 : ABI_FREE(gred)
517 2852 : ABI_FREE(nband)
518 2852 : ABI_FREE(npwtot)
519 2852 : ABI_FREE(results_out)
520 2852 : ABI_FREE(xred)
521 :
522 : ! 20) Write the final timing, close the output file, and write a final line to the log file
523 2852 : call timein(tsec(1),tsec(2))
524 2852 : tsec(1)=tsec(1)-tcpui
525 2852 : tsec(2)=tsec(2)-twalli
526 :
527 : ! Get number of comments/warnings
528 2852 : call specialmsg_getcount(ncomment,nwarning,nexit)
529 2852 : call libpaw_spmsg_getcount(ncomment_paw,nwarning_paw,nexit_paw)
530 2852 : ncomment=ncomment+ncomment_paw;nwarning=nwarning+nwarning_paw;nexit=nexit+nexit_paw
531 2852 : warn_fmt='(a,i6,a,i6,a)'
532 2852 : if (nwarning<10000.and.ncomment<10000) warn_fmt='(a,i5,a,i5,a)'
533 2852 : if (nwarning<1000 .and.ncomment<1000 ) warn_fmt='(a,i4,a,i4,a)'
534 :
535 : #if defined HAVE_MPI
536 2852 : write(std_out,'(a,i4,a,f13.1,a,f13.1)')' Proc.',mpi_enregs(1)%me,' individual time (sec): cpu=',tsec(1),' wall=',tsec(2)
537 2852 : if(me==0)then
538 2296 : write(ab_out,'(3a,i4,a,f13.1,a,f13.1)')'-',ch10,'- Proc.',me,' individual time (sec): cpu=',tsec(1),' wall=',tsec(2)
539 : end if
540 2852 : call xmpi_sum(tsec, xmpi_world, ierr)
541 : #else
542 : write(ab_out, '(a,a,a,f13.1,a,f13.1)' )'-',ch10,'- Proc. 0 individual time (sec): cpu=',tsec(1),' wall=',tsec(2)
543 : #endif
544 :
545 231012 : write(msg,'(a,80a,a,a,a)' ) ch10,('=',mu=1,80),ch10,ch10,' Calculation completed.'
546 2852 : call wrtout(ab_out, msg)
547 2852 : write(msg,fmt=warn_fmt) '.Delivered',nwarning,' WARNINGs and',ncomment,' COMMENTs to log file.'
548 2852 : if (nexit/=0) write(msg,'(3a)') trim(msg),ch10,' Note : exit requested by the user.'
549 2852 : call wrtout(ab_out, msg)
550 :
551 2852 : if (me==0) then
552 2296 : write(ab_out, '(a,f13.1,a,f13.1)' )'+Overall time at end (sec) : cpu=',tsec(1),' wall=',tsec(2)
553 2296 : write(msg, '(a,a)' ) ch10,' Calculation completed.'
554 2296 : call wrtout(std_out, msg)
555 2296 : write(msg,fmt=warn_fmt) '.Delivered',nwarning,' WARNINGs and',ncomment,' COMMENTs to log file.'
556 2296 : if (nexit/=0) write(msg,'(3a)') trim(msg),ch10,' Note : exit requested by the user.'
557 2296 : call wrtout(std_out, msg)
558 : end if
559 :
560 2852 : if (me==0) then
561 : ! Write YAML document with the final summary.
562 : ! We use this doc to test whether the calculation is completed.
563 2296 : write(std_out,"(a)")
564 2296 : write(std_out,"(a)")"--- !FinalSummary"
565 2296 : write(std_out,"(a)")"program: abinit"
566 2296 : write(std_out,"(2a)")"version: ",trim(abinit_version)
567 2296 : write(std_out,"(2a)")"start_datetime: ",start_datetime
568 2296 : write(std_out,"(2a)")"end_datetime: ",asctime()
569 2296 : write(std_out,"(a,f13.1)")"overall_cpu_time: ",tsec(1)
570 2296 : write(std_out,"(a,f13.1)")"overall_wall_time: ",tsec(2)
571 2296 : write(std_out,"(2a)")"exit_requested_by_user: ",yesno(nexit /= 0)
572 2296 : write(std_out,"(2a)")"timelimit: ",trim(get_timelimit_string())
573 2296 : write(std_out,"(a)")"pseudos: "
574 5408 : do ii=1,npsp
575 5408 : write(std_out,"(4a)")" ",ljust(znucl2symbol(pspheads(ii)%znuclpsp), 4),": ",trim(pspheads(ii)%md5_checksum)
576 : end do
577 2296 : write(std_out,"(a,i0)")"usepaw: ",dtsets(1)%usepaw
578 2296 : write(std_out,"(a,i0)")"mpi_procs: ",xmpi_comm_size(xmpi_world)
579 2296 : write(std_out,"(a,i0)")"omp_threads: ",xomp_get_num_threads(open_parallel=.True.)
580 2296 : write(std_out,"(a,i0)")"num_warnings: ",nwarning
581 2296 : write(std_out,"(a,i0)")"num_comments: ",ncomment
582 2296 : write(std_out,"(a)")"..."
583 2296 : call flush_unit(std_out)
584 : end if
585 :
586 2852 : if (me==0) then
587 2296 : if (xml_output) call outxml_finalise(tsec, values)
588 : #ifndef HAVE_MEM_PROFILING
589 2296 : close(unit=ab_out)
590 : #endif
591 : end if
592 :
593 : ! 21) Eventual cleaning of MPI (and/or GPU) run
594 2852 : call clnmpi_img(mpi_enregs(0))
595 16760 : do ii=1,ndtset_alloc
596 13908 : if(mpi_enregs(ii)%me<0) cycle
597 13908 : call clnmpi_img(mpi_enregs(ii))
598 13908 : call clnmpi_grid(mpi_enregs(ii))
599 13908 : call clnmpi_atom(mpi_enregs(ii))
600 16760 : call clnmpi_pert(mpi_enregs(ii))
601 : end do
602 19612 : do ii=0,max(1,ndtset)
603 19612 : call destroy_mpi_enreg(mpi_enregs(ii))
604 : end do
605 22464 : ABI_FREE(mpi_enregs)
606 :
607 : ! If memory profiling is activated, check if bigdft plugin is used or not
608 2852 : print_mem_report = 1
609 16760 : do ii=1,ndtset_alloc
610 16760 : if ((dtsets(ii)%usewvl == 1) .or. (dtsets(ii)%icoulomb > 0)) then
611 0 : print_mem_report = 0; exit
612 : end if
613 : end do
614 :
615 : #if defined HAVE_BIGDFT
616 : if (timopt==10) then
617 : call wvl_timing(xmpi_world,'== POSTPRC','PR')
618 : end if
619 : call f_lib_finalize()
620 : #endif
621 :
622 : ! Here we deallocate dtsets. Do not access dtsets after this line!
623 19612 : do ii=0,size(dtsets)-1,1
624 19612 : call dtsets(ii)%free()
625 : end do
626 22464 : ABI_FREE(dtsets)
627 6724 : do ii=1,size(pspheads)
628 3872 : ABI_SFREE(pspheads(ii)%nproj)
629 6724 : ABI_SFREE(pspheads(ii)%nprojso)
630 : enddo
631 9576 : ABI_FREE(pspheads)
632 :
633 : #if defined HAVE_GPU_CUDA
634 : call unsetdevice_cuda(gpu_option)
635 : #endif
636 :
637 2852 : call xpapi_shutdown()
638 :
639 2852 : call pstat_proc%print(comm=xmpi_world _FILE_LINE_ARGS_)
640 :
641 : ! Writes information on file about the memory before ending mpi module, if memory profiling is enabled
642 2852 : call abinit_doctor(filnam(4), print_mem_report=print_mem_report)
643 :
644 2852 : call flush_unit(std_out)
645 2852 : call flush_unit(ab_out)
646 :
647 2852 : if (me == 0) close(unit=ab_out)
648 :
649 2854 : 100 call xmpi_end()
650 :
651 8622 : end program abinit
652 : !!***
|