TABLE OF CONTENTS


ABINIT/abinit [ Programs ]

[ Top ] [ Programs ]

NAME

 abinit

FUNCTION

 Main routine for conducting Density-Functional Theory calculations or Many-Body Perturbation Theory calculations.

COPYRIGHT

 Copyright (C) 1998-2018 ABINIT group (DCA, XG, GMR, MKV, MT)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt .

NOTES

 The new user is strongly adviced to read the
 latest version of the file ~abinit/doc/users/new_user_guide.html
 before trying to modify or even use the code.
 Even experienced users of the code should also be careful in coding,
 please read the latest version of the file ~abinit/doc/developers/rules_coding

 The present main routine drives the following operations :

 1) Eventually initialize MPI
 2) Initialize overall timing of run
 3) Print greeting for interactive user and
    Read names of files (input, output, rootinput, rootoutput, roottemporaries),
    create the name of the status file, initialize the status subroutine.
 4) Open output file and print herald at top of output and log files
 5) Read the input file, and store the information in a long string of characters
 6) Take ndtset from the input string, then allocate
    the arrays whose dimensions depends only on ndtset
 7) Continue to analyze the input string, and allocate the remaining arrays.
    Also modulate the timing according to timopt.
 8) Finish to read the "file" file completely,
    and also initialize pspheads (the pseudopotential header information)
 9) Provide defaults for the variables that have not yet been initialized.
 10) Perform some global initialization, depending on the value of
 pseudopotentials, parallelism variables, or macro input variables
 11) Call the main input routine.
 12) Echo input data to output file and log file
 13) Perform additional checks on input data
  At this stage, all the information from the "files" file and "input" file
  have been read and checked.
 14) Print more information, and activate GPU
 ___________________________________________
 15) Perform main calculation  (call driver)
 -------------------------------------------

 16) Give final echo of coordinates, etc.
 17) Timing analysis
 18) Bibliographical recommendations
 19) Delete the status file, and, for build-in tests, analyse the correctness of results
 20) Write the final timing, close the output file, and write a final line to the log file
 21) Eventual cleaning of MPI run

TODO

  Reduce the number of tasks in this main routine ! Create subroutine to make the full init of input variables,
  including the echo ...

INPUTS

  (main routine)

OUTPUT

  (main routine)

PARENTS

CHILDREN

      ab7_invars_free,ab7_invars_get_abinit_vars,ab7_invars_load
      ab7_invars_set_flags,abi_io_redirect,abimem_init,abinit_doctor
      bigdft_init_errors,bigdft_init_timing_categories,chkinp,chkvars
      clnmpi_atom,clnmpi_grid,clnmpi_img,clnmpi_pert,date_and_time
      delete_file,destroy_mpi_enreg,destroy_results_out,driver,dump_config
      dump_cpp_options,dump_optim,f_lib_finalize,f_lib_initialize,flush_unit
      gather_results_out,herald,init_results_out,iofn1,libpaw_spmsg_getcount
      memory_eval,mpi_allreduce,mpi_setup,nctk_test_mpiio,out_acknowl,outvars
      outxml_finalise,outxml_open,parsefile,paw_setup_free,print_kinds
      setdevice_cuda,specialmsg_getcount,status,testfi,timab,timana
      time_set_papiopt,timein,unsetdevice_cuda,wrtout,xmpi_init
      xmpi_show_info,xomp_show_info,xpapi_init,xpapi_show_info,xpapi_shutdown

SOURCE

 86 #if defined HAVE_CONFIG_H
 87 #include "config.h"
 88 #endif
 89 
 90 #include "abi_common.h"
 91 
 92 program abinit
 93 
 94  use defs_basis
 95  use defs_datatypes
 96  use defs_abitypes
 97  use m_ab7_invars
 98  use m_build_info
 99  use m_cppopts_dumper
100  use m_optim_dumper
101  use m_abicore
102  use m_results_out
103  use m_xmpi
104  use m_xomp
105  use m_xpapi
106  use m_errors
107  use m_argparse
108  use m_nctk
109 #if defined HAVE_MPI2
110  use mpi
111 #endif
112 
113  use m_time ,       only : asctime, sec2str, timein, time_set_papiopt, timab
114  use m_fstrings,    only : sjoin, strcat, itoa, yesno, ljust
115  use m_io_tools,    only : open_file, flush_unit, delete_file, num_opened_units, show_units
116  use m_specialmsg,  only : specialmsg_getcount, herald
117  use m_exit,        only : get_timelimit_string
118  use m_atomdata,    only : znucl2symbol
119  use m_libpaw_tools,only : libpaw_spmsg_getcount
120  use m_mpinfo,      only : destroy_mpi_enreg, clnmpi_img, clnmpi_grid, clnmpi_atom, clnmpi_pert
121  use m_memeval,     only : memory_eval
122  use m_chkinp,      only : chkinp
123  use m_dtset,       only : chkvars
124  use m_dtfil,       only : iofn1, status
125  use m_outxml,      only : outxml_open, outxml_finalise
126  use m_parser,      only : parsefile
127  use m_out_acknowl, only : out_acknowl
128  use m_timana,      only : timana
129  use m_builtin_tests, only : testfi
130  use m_mpi_setup,     only : mpi_setup
131  use m_outvars,       only : outvars
132  use m_driver,       only : driver
133 #ifdef HAVE_GPU_CUDA
134  use m_initcuda,     only: setdevice_cuda,unsetdevice_cuda
135 #endif
136 #if defined HAVE_BIGDFT
137  use BigDFT_API,    only : bigdft_init_errors,bigdft_init_timing_categories
138 #endif
139 
140 !This section has been created automatically by the script Abilint (TD).
141 !Do not modify the following lines by hand.
142 #undef ABI_FUNC
143 #define ABI_FUNC 'abinit'
144 !End of the abilint section
145 
146  implicit none
147 
148 #if defined HAVE_MPI1
149  include 'mpif.h'
150 #endif
151 
152 !Arguments -----------------------------------
153 !Local variables-------------------------------
154 !
155 !===============================================================================
156 !  abinit_version designate overall code version
157 !  mpw=maximum number of planewaves in basis sphere
158 !  unit numbers (ab_in,ab_out,std_out,tmp_unit) have been defined in defs_basis.f .
159 !  The array filnam is used for the name of input and output files,
160 !  and roots for generic input, output or temporary files.
161 !  Pseudopotential file names are set in iofn2, and are contained in pspheads.
162 !  The name filstat will be needed beyond gstate to check
163 !  the appearance of the "exit" flag, to make a hasty exit, as well as
164 !  in order to output the status of the computation.
165 !==============================================================================
166 ! Declarations
167 ! Define "level of the routine", for debugging purposes
168  integer,parameter :: level=1
169  integer :: choice,dmatpuflag,ierr,iexit,ii,iounit,dtsetsId,ios
170  integer :: lenstr,me,print_mem_report
171  integer :: mu,natom,ncomment,ncomment_paw,ndtset
172  integer :: ndtset_alloc,nexit,nexit_paw,nfft,nkpt,npsp
173  integer :: nsppol,nwarning,nwarning_paw,papiopt,prtvol,timopt,use_gpu_cuda
174  integer,allocatable :: nband(:),npwtot(:)
175  real(dp) :: etotal
176  real(dp) :: tcpui,twalli
177  real(dp) :: strten(6),tsec(2)
178  real(dp),allocatable :: fred(:,:),xred(:,:)
179  character(len=24) :: codename
180  character(len=24) :: start_datetime
181  character(len=5000) :: message
182  character(len=strlen) :: string
183  character(len=fnlen) :: filstat
184  character(len=fnlen) :: filnam(5)
185  type(args_t) :: args
186  type(dataset_type),pointer  :: dtsets(:)
187  type(MPI_type),pointer :: mpi_enregs(:)
188  type(pspheader_type),pointer :: pspheads(:)
189  type(results_out_type),allocatable,target :: results_out(:)
190  type(results_out_type),pointer :: results_out_all(:)
191  type(ab_dimensions) :: mxvals
192  logical :: test_img,test_exit,use_results_all,xml_output=.false.
193  integer :: values(8)
194  character(len=5) :: strzone
195  character(len=8) :: strdat
196  character(len=10) :: strtime
197  character(len=13) :: warn_fmt
198 #ifdef HAVE_GPU_CUDA
199  integer :: gpu_devices(5)
200 #endif
201 
202 !******************************************************************
203 
204 !0) Change communicator for I/O (mandatory!)
205  call abi_io_redirect(new_io_comm=xmpi_world)
206 
207  !call xlf_set_sighandler()
208 
209 !------------------------------------------------------------------------------
210 
211 !1) Eventually initialize MPI
212 !Pay attention: it may be initialzed again in finddistrproc
213 
214  call xmpi_init()
215  me=xmpi_comm_rank(xmpi_world)
216 
217  ! Parse command line arguments.
218  args = args_parser(); if (args%exit /= 0) goto 100
219 
220 !Initialize memory profiling if it is activated
221 !if a full memocc.prc report is desired, set the argument of abimem_init to "2" instead of "0"
222 !note that memocc.prc files can easily be multiple GB in size so don't use this option normally
223 #ifdef HAVE_MEM_PROFILING
224  call abimem_init(args%abimem_level)
225 ! call abimem_init(2)
226 #endif
227 
228 !------------------------------------------------------------------------------
229 
230 !2) Initialize overall timing of run:
231  call xpapi_init()
232  call xpapi_show_info(unit=std_out,mode_paral="COLL")
233 
234  start_datetime = asctime()
235 
236  call timein(tcpui,twalli)
237 
238  call timab(1,0,tsec)
239 
240 !Start to accumulate time for the entire run. The end of accumulation is in timana.f
241  call timab(1,1,tsec)
242 
243 !------------------------------------------------------------------------------
244 
245 !3) Print greeting for interactive user,
246 !read names of files (input, output, rootinput, rootoutput, roottemporaries),
247 !create the name of the status file, initialize the status subroutine.
248 
249  call timab(41,3,tsec)
250 
251  call iofn1(filnam,filstat,xmpi_world)
252 
253 !------------------------------------------------------------------------------
254 
255 !4) Open output file and print herald at top of output and log files
256 
257  if (me==0) then
258 #ifdef FC_NAG
259    open(unit=ab_out,file=filnam(2),form='formatted',status='new', action="write", recl=ABI_RECL, iomsg=message, iostat=ios)
260 #else
261    open(unit=ab_out,file=filnam(2),form='formatted',status='new', action="write", iomsg=message, iostat=ios)
262 #endif
263    ABI_CHECK(ios == 0, message)
264    rewind (unit=ab_out)
265    codename='ABINIT'//repeat(' ',18)
266    call herald(codename,abinit_version,ab_out)
267    call herald(codename,abinit_version,std_out)
268    call dump_config(std_out)
269    call dump_optim(std_out)
270    call dump_cpp_options(std_out)
271 !  Write names of files
272    write(message, '(a,a,a,a,a,a,a,a,a,a,a,a)' )&
273 &   '- input  file    -> ',trim(filnam(1)),ch10,&
274 &   '- output file    -> ',trim(filnam(2)),ch10,&
275 &   '- root for input  files -> ',trim(filnam(3)),ch10,&
276 &   '- root for output files -> ',trim(filnam(4)),ch10
277    call wrtout(ab_out,message,'COLL')
278    call wrtout(std_out,message,'COLL')
279  end if
280 
281  ! Test if the netcdf library supports MPI-IO
282  call nctk_test_mpiio()
283 
284 !------------------------------------------------------------------------------
285 
286 !5) Read the file, stringify it and return the number of datasets.
287  call parsefile(filnam(1), lenstr, ndtset, string, xmpi_world)
288 
289 !------------------------------------------------------------------------------
290 
291 !6~11) Call the parser from the parser module.
292  call ab7_invars_set_flags(.true., .true., status_file = filstat, timab_tsec = tsec)
293  call ab7_invars_load(dtsetsId, string, lenstr, ndtset, .true., .true.)
294 
295  call timab(44,1,tsec)
296 
297  call ab7_invars_get_abinit_vars(dtsetsId, dtsets, pspheads,mxvals, papiopt, timopt, dmatpuflag)
298  ndtset_alloc = size(dtsets) - 1
299  npsp = size(pspheads)
300 
301 #if defined HAVE_BIGDFT
302  call f_lib_initialize()
303  call bigdft_init_errors()
304  call bigdft_init_timing_categories()
305 #endif
306 
307 !Enable PAPI timers
308  call time_set_papiopt(papiopt)
309 
310  ABI_DATATYPE_ALLOCATE(mpi_enregs,(0:max(1,ndtset)))
311  call mpi_setup(dtsets,filnam,lenstr,mpi_enregs,ndtset,ndtset_alloc,string)
312 
313  call memory_eval(dtsets,ab_out,mpi_enregs,ndtset,ndtset_alloc,npsp,pspheads)
314 
315 !------------------------------------------------------------------------------
316 
317 !12) Echo input data to output file and log file
318 
319  call status(0,filstat,iexit,level,'call outvars(1)')
320 
321 !For evolving variables, and results
322  ABI_DATATYPE_ALLOCATE(results_out,(0:ndtset_alloc))
323 
324 !Initialize results_out datastructure
325 
326  call init_results_out(dtsets,1,1,mpi_enregs,&
327 & mxvals%natom,&
328 & mxvals%mband_upper,&
329 & mxvals%nkpt,&
330 & npsp,&
331 & mxvals%nsppol,&
332 & mxvals%ntypat,&
333 & results_out)
334 
335 !Gather contributions to results_out from images of the cell, if needed
336  test_img=(mxvals%nimage/=1.and.maxval(dtsets(:)%npimage)>1)
337  use_results_all=.false.
338  if (test_img) then
339    use_results_all=(me==0)
340    if (use_results_all)  then
341      ABI_DATATYPE_ALLOCATE(results_out_all,(0:ndtset_alloc))
342    end if
343 
344    call gather_results_out(dtsets,mpi_enregs,results_out,results_out_all,use_results_all,&
345 &   allgather=.false.,master=0)
346 
347  else
348    results_out_all => results_out
349  end if
350 
351  if(me==0) then
352 
353 !  Echo input to output file on unit ab_out, and to log file on unit 06 :
354    choice=1
355    do ii=1,2
356      if(ii==1)iounit=ab_out
357      if(ii==2)iounit=std_out
358 
359      call outvars (choice,dmatpuflag,dtsets,trim(filnam(4)),&
360 &     iounit, mxvals,  ndtset,ndtset_alloc,npsp,results_out_all,timopt)
361    end do
362 
363    if (dtsets(1)%prtxml == 1) then
364      call outxml_open(trim(filnam(4)))
365      call date_and_time(strdat,strtime,strzone,values)
366      xml_output = .true.
367    else
368      xml_output = .false.
369    end if
370 
371  end if ! End of me==0 section
372 
373 !Clean memory
374  if (test_img.and.me==0) then
375    call destroy_results_out(results_out_all)
376    ABI_DATATYPE_DEALLOCATE(results_out_all)
377  end if
378 
379 !This synchronization is not strictly needed, but without it,
380 !there are problems with Tv1#93 in parallel, PGI compiler, on Intel/PC
381 
382  call abi_io_redirect(new_io_comm=xmpi_world)
383 
384  call timab(44,2,tsec)
385 
386 !------------------------------------------------------------------------------
387 
388 !13) Perform additional checks on input data
389 
390  call timab(45,3,tsec)
391  call status(0,filstat,iexit,level,'call chkinp   ')
392 
393  call chkinp(dtsets,ab_out,mpi_enregs,ndtset,ndtset_alloc,npsp,pspheads)
394 
395 !Check whether the string only contains valid keywords
396  call chkvars(string)
397 
398 !At this stage, all the information from the "files" file and "input" file have been read and checked.
399 
400 !------------------------------------------------------------------------------
401 
402 !14) Print more information, and activate GPU
403 
404  if (me==0) then
405    call print_kinds(std_out)     ! Printout of kinds and precisions.
406    call xomp_show_info(std_out)  ! Info on the openMP environment.
407    call xmpi_show_info(std_out)  ! Info on the MPI environment.
408  end if
409 
410 !Eventually activate GPU
411  use_gpu_cuda=0
412 #if defined HAVE_GPU_CUDA
413  gpu_devices(:)=-1
414  do ii=1,ndtset_alloc
415    if (dtsets(ii)%use_gpu_cuda==1) then
416      use_gpu_cuda=1
417      gpu_devices(:)=dtsets(ii)%gpu_devices(:)
418    end if
419  end do
420  call setdevice_cuda(gpu_devices,use_gpu_cuda)
421 #endif
422 
423 !------------------------------------------------------------------------------
424 
425 !15) Perform main calculation
426 !The timing is done in gstate
427 
428  call timab(45,2,tsec)
429 
430  call status(0,filstat,iexit,level,'call driver   ')
431 
432  test_exit=.false.
433  prtvol=dtsets(1)%prtvol
434  if (prtvol==-level .or. prtvol==-2.or.args%dry_run/=0) then
435    write(message,'(a,a,i0,a)')ch10,&
436 &   ' abinit : before driver, prtvol=',prtvol,', debugging mode => will skip driver '
437    call wrtout(ab_out,message,'COLL')
438    call wrtout(std_out,message,'COLL')
439    test_exit=.true.
440  end if
441 
442  if(.not.test_exit)then
443    call driver(abinit_version,tcpui,dtsets,filnam,filstat,&
444 &   mpi_enregs,ndtset,ndtset_alloc,npsp,pspheads,results_out)
445  end if
446 
447  call status(0,filstat,iexit,level,'after driver  ')
448 
449 !------------------------------------------------------------------------------
450 
451 !16) Give final echo of coordinates, etc.
452  call timab(46,1,tsec)
453 
454  write(message,'(a,a,a,62a,80a)') ch10,&
455 & '== END DATASET(S) ',('=',mu=1,62),ch10,('=',mu=1,80)
456  call wrtout(ab_out,message,'COLL')
457  call wrtout(std_out,message,'COLL')
458 
459 !Gather contributions to results_out from images of the cell, if needed
460  if (test_img) then
461    if (use_results_all)  then
462      ABI_DATATYPE_ALLOCATE(results_out_all,(0:ndtset_alloc))
463    end if
464 
465    call gather_results_out(dtsets,mpi_enregs,results_out,results_out_all,use_results_all,&
466 &   allgather=.false.,master=0)
467  end if
468 
469  if(me==0) then
470    if(test_exit)then
471      write(message,'(a,a,i0,a)')ch10,&
472 &     ' abinit : before driver, prtvol=',prtvol,', debugging mode => will skip outvars '
473      call wrtout(ab_out,message,'COLL')
474      call wrtout(std_out,message,'COLL')
475    else
476 !    Echo input to output file on unit ab_out, and to log file on unit std_out.
477      choice=2
478      do ii=1,2
479        if(ii==1)iounit=ab_out
480        if(ii==2)iounit=std_out
481        write(iounit,*)' '
482        call outvars (choice,dmatpuflag,dtsets,trim(filnam(4)),&
483 &       iounit,mxvals,ndtset,ndtset_alloc,npsp,results_out_all,timopt)
484        if(ii==2)write(std_out,*)' '
485      end do
486    end if
487  end if ! me==0
488 
489 !Clean memory
490  if (test_img.and.me==0) then
491    call destroy_results_out(results_out_all)
492    ABI_DATATYPE_DEALLOCATE(results_out_all)
493  else
494    nullify(results_out_all)
495  end if
496 
497 !In prevision of the next two calls, some variables need to be transfered.
498 !They concern the case ndtset<2, and nimage=1 so take first value.
499  natom=dtsets(1)%natom ; nkpt=dtsets(1)%nkpt ; nsppol=dtsets(1)%nsppol
500  nfft=dtsets(1)%nfft
501  ABI_ALLOCATE(nband,(nkpt*nsppol))
502  ABI_ALLOCATE(npwtot,(nkpt))
503  ABI_ALLOCATE(fred,(3,natom))
504  ABI_ALLOCATE(xred,(3,natom))
505  etotal=results_out(1)%etotal(1)
506  fred(:,:)  =results_out(1)%fred(:,1:natom,1)
507  nband(:)   =dtsets(1)%nband(1:nkpt*nsppol)
508  npwtot(:)  =results_out(1)%npwtot(1:nkpt,1)
509  strten(:)  =results_out(1)%strten(:,1)
510  xred(:,:)  =results_out(1)%xred(:,1:natom,1)
511 
512  call timab(46,2,tsec)
513 
514 !------------------------------------------------------------------------------
515 
516 !17) Timing analysis
517  if(timopt/=0)then
518    call status(0,filstat,iexit,level,'call timana   ')
519    call timana (mpi_enregs(1), natom, nband, ndtset, nfft, nkpt, npwtot, nsppol, timopt)
520  else
521 #if defined HAVE_MPI
522    if(me==0)then ! This is for the automatic tests
523      write(ab_out,'(5a)')ch10,ch10,'- Timing analysis has been suppressed with timopt=0',ch10,ch10
524    end if
525 #endif
526  end if
527 
528 !------------------------------------------------------------------------------
529 
530 !18) Bibliographical recommendations
531  if(me==0) then
532    if(test_exit)then
533      write(message,'(a,a,i0,a)')ch10,&
534 &     ' abinit : before driver, prtvol=',prtvol,', debugging mode => will skip acknowledgments '
535      call wrtout(ab_out,message,'COLL')
536      call wrtout(std_out,message,'COLL')
537    else
538      do ii=1,2
539        if(ii==1)iounit=ab_out
540        if(ii==2)iounit=std_out
541        call out_acknowl(dtsets,iounit,ndtset_alloc,npsp,pspheads)
542      end do
543    end if
544  end if ! me==0
545 
546 !------------------------------------------------------------------------------
547 
548 !19) Delete the status file, and, for build-in tests, analyse the correctness of results.
549 
550  call status(0,filstat,iexit,level,'end echo status')
551  if(ndtset==0)then
552    call testfi(dtsets(1)%builtintest,etotal,filstat,fred,natom,strten,xred)
553  else
554    call delete_file(filstat, ierr)
555  end if
556 
557 !One should have here the explicit deallocation of all arrays
558  call destroy_results_out(results_out)
559 
560  ABI_DEALLOCATE(fred)
561  ABI_DEALLOCATE(nband)
562  ABI_DEALLOCATE(npwtot)
563  ABI_DATATYPE_DEALLOCATE(results_out)
564  ABI_DEALLOCATE(xred)
565 
566 !20) Write the final timing, close the output file, and write a final line to the log file
567 
568  call timein(tsec(1),tsec(2))
569  tsec(1)=tsec(1)-tcpui
570  tsec(2)=tsec(2)-twalli
571 
572 !Get number of comments/warnings
573  call specialmsg_getcount(ncomment,nwarning,nexit)
574  call libpaw_spmsg_getcount(ncomment_paw,nwarning_paw,nexit_paw)
575  ncomment=ncomment+ncomment_paw;nwarning=nwarning+nwarning_paw;nexit=nexit+nexit_paw
576  warn_fmt='(a,i6,a,i6,a)'
577  if (nwarning<10000.and.ncomment<10000) warn_fmt='(a,i5,a,i5,a)'
578  if (nwarning<1000 .and.ncomment<1000 ) warn_fmt='(a,i4,a,i4,a)'
579 
580 #if defined HAVE_MPI
581  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)
582  if(me==0)then
583    write(ab_out,'(3a,i4,a,f13.1,a,f13.1)')'-',ch10,'- Proc.',me,' individual time (sec): cpu=',tsec(1),'  wall=',tsec(2)
584  end if
585  call xmpi_sum(tsec, xmpi_world, ierr)
586 #else
587  write(ab_out, '(a,a,a,f13.1,a,f13.1)' )'-',ch10,'- Proc.   0 individual time (sec): cpu=',tsec(1),'  wall=',tsec(2)
588 #endif
589 
590  write(message,'(a,80a,a,a,a)' ) ch10,('=',mu=1,80),ch10,ch10,' Calculation completed.'
591  call wrtout(ab_out,message,'COLL')
592  write(message,fmt=warn_fmt) '.Delivered',nwarning,' WARNINGs and',ncomment,' COMMENTs to log file.'
593  if (nexit/=0) write(message,'(3a)') trim(message),ch10,' Note : exit requested by the user.'
594  call wrtout(ab_out,message,'COLL')
595 
596  if (me==0) then
597    write(ab_out, '(a,f13.1,a,f13.1)' )'+Overall time at end (sec) : cpu=',tsec(1),'  wall=',tsec(2)
598    write(message, '(a,a)' ) ch10,' Calculation completed.'
599    call wrtout(std_out,message,'COLL')
600    write(message,fmt=warn_fmt) '.Delivered',nwarning,' WARNINGs and',ncomment,' COMMENTs to log file.'
601    if (nexit/=0) write(message,'(3a)') trim(message),ch10,' Note : exit requested by the user.'
602    call wrtout(std_out,message,'COLL')
603  end if
604 
605  if (me==0) then
606 !  Write YAML document with the final summary.
607 !  We use this doc to test whether the calculation is completed.
608    write(std_out,"(a)")
609    write(std_out,"(a)")"--- !FinalSummary"
610    write(std_out,"(a)")"program: abinit"
611    write(std_out,"(2a)")"version: ",trim(abinit_version)
612    write(std_out,"(2a)")"start_datetime: ",start_datetime
613    write(std_out,"(2a)")"end_datetime: ",asctime()
614    write(std_out,"(a,f13.1)")"overall_cpu_time: ",tsec(1)
615    write(std_out,"(a,f13.1)")"overall_wall_time: ",tsec(2)
616    write(std_out,"(2a)")"exit_requested_by_user: ",yesno(nexit /= 0)
617    write(std_out,"(2a)")"timelimit: ",trim(get_timelimit_string())
618    write(std_out,"(a)")"pseudos: "
619    do ii=1,npsp
620      write(std_out,"(4a)")"    ",ljust(znucl2symbol(pspheads(ii)%znuclpsp), 4),": ",trim(pspheads(ii)%md5_checksum)
621    end do
622    write(std_out,"(a,i0)")"usepaw: ",dtsets(1)%usepaw
623    write(std_out,"(a,i0)")"mpi_procs: ",xmpi_comm_size(xmpi_world)
624    write(std_out,"(a,i0)")"omp_threads: ",xomp_get_num_threads(open_parallel=.True.)
625    write(std_out,"(a,i0)")"num_warnings: ",nwarning
626    write(std_out,"(a,i0)")"num_comments: ",ncomment
627    write(std_out,"(a)")"..."
628    call flush_unit(std_out)
629  end if
630 
631  if (me==0) then
632    if (xml_output) then
633      call outxml_finalise(tsec, values)
634    end if
635 #ifndef HAVE_MEM_PROFILING
636    close(unit=ab_out)
637 #endif
638  end if
639 
640 !21) Eventual cleaning of MPI (and/or GPU) run
641  call clnmpi_img(mpi_enregs(0))
642  do ii=1,ndtset_alloc
643    if(mpi_enregs(ii)%me<0) cycle
644    call clnmpi_img(mpi_enregs(ii))
645    call clnmpi_grid(mpi_enregs(ii))
646    call clnmpi_atom(mpi_enregs(ii))
647    call clnmpi_pert(mpi_enregs(ii))
648  end do
649  do ii=0,max(1,ndtset)
650    call destroy_mpi_enreg(mpi_enregs(ii))
651  end do
652  ABI_DATATYPE_DEALLOCATE(mpi_enregs)
653 
654 !If memory profiling is activated, check if bigdft plugin is used or not
655  print_mem_report = 1
656  do ii=1,ndtset_alloc
657    if ((dtsets(ii)%usewvl == 1) .or. (dtsets(ii)%icoulomb > 0)) then
658      print_mem_report = 0
659      exit
660    end if
661  end do
662  ! Here we deallocate dtsets. Do not access dtsets after this line!
663  call ab7_invars_free(dtsetsId)
664 
665 #if defined HAVE_BIGDFT
666  call f_lib_finalize()
667 #endif
668 
669 #if defined HAVE_GPU_CUDA
670  call unsetdevice_cuda(use_gpu_cuda)
671 #endif
672 
673  call xpapi_shutdown()
674 
675 !Writes information on file about the memory before ending mpi module, if memory profiling is enabled
676  !ABI_ALLOCATE(nband, (2))
677  call abinit_doctor(filnam(4), print_mem_report=print_mem_report)
678 
679  call flush_unit(std_out)
680  call flush_unit(ab_out)
681 
682  if (me == 0) close(unit=ab_out)
683 
684  100 call xmpi_end()
685 
686  end program abinit