LCOV - code coverage report
Current view: top level - src/98_main - abinit.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.9 % 226 210
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 2 2

            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              : !!***
        

Generated by: LCOV version 2.3-1