LCOV - code coverage report
Current view: top level - src/95_drive - m_argparse.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 20.6 % 345 71
Test Date: 2026-11-08 00:10:28 Functions: 30.8 % 13 4
Branches: 13.4 % 463 62

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_argparse
       2                 :             : !! NAME
       3                 :             : !! m_argparse
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!   Simple argument parser used in main programs
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2008-2026 ABINIT group (MG)
      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                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_argparse
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_abicore
      26                 :             :  use m_errors
      27                 :             :  use m_xmpi
      28                 :             :  use m_xomp
      29                 :             :  use m_xieee
      30                 :             :  use m_abi_linalg
      31                 :             :  use m_fft
      32                 :             :  use m_exit
      33                 :             :  use m_clib
      34                 :             :  use m_nctk
      35                 :             : 
      36                 :             :  use m_build_info,      only : dump_config, abinit_version
      37                 :             :  use m_io_tools,        only : open_file, file_exists, enforce_fortran_io
      38                 :             :  use m_cppopts_dumper,  only : dump_cpp_options
      39                 :             :  use m_optim_dumper,    only : dump_optim
      40                 :             :  use m_fstrings,        only : atoi, atof, itoa, firstchar, startswith, endswith, sjoin, find_and_select
      41                 :             :  use m_time,            only : str2sec
      42                 :             :  use m_libpaw_tools,    only : libpaw_log_flag_set
      43                 :             :  use m_ipi,             only : ipi_setup
      44                 :             : 
      45                 :             :  implicit none
      46                 :             : 
      47                 :             :  private
      48                 :             : 
      49                 :             :  public :: get_arg         !  Parse scalar argument from command line. Return exit code.
      50                 :             : 
      51                 :             :  interface get_arg
      52                 :             :    module procedure get_arg_int
      53                 :             :    module procedure get_arg_dp
      54                 :             :    module procedure get_arg_str
      55                 :             :    module procedure get_arg_bool
      56                 :             :  end interface get_arg
      57                 :             : 
      58                 :             :  public :: get_arg_list    ! Parse array argument from command line. Return exit code.
      59                 :             : 
      60                 :             :  interface get_arg_list
      61                 :             :    module procedure get_arg_list_int
      62                 :             :    module procedure get_arg_list_dp
      63                 :             :  end interface get_arg_list
      64                 :             : 
      65                 :             :  public :: get_start_step_num    ! Parse string from command line in the format "start:step:num"
      66                 :             :                                  ! defining an arithmetic progression.
      67                 :             :  public :: parse_kargs           !  Parse command line arguments, return options related to k-point sampling
      68                 :             : !!***
      69                 :             : 
      70                 :             : !!****t* m_argparse/args_t
      71                 :             : !! NAME
      72                 :             : !! args_t
      73                 :             : !!
      74                 :             : !! FUNCTION
      75                 :             : !! Stores command line options
      76                 :             : !!
      77                 :             : !! SOURCE
      78                 :             : 
      79                 :             :  type,public :: args_t
      80                 :             : 
      81                 :             :    integer :: exit = 0
      82                 :             :     ! /=0 to exit after having parsed the command line options.
      83                 :             : 
      84                 :             :    integer :: abimem_level = 0
      85                 :             :     ! Options for memory profiling. See m_profiling_abi
      86                 :             : 
      87                 :             :    integer :: dry_run = 0
      88                 :             :     ! /= 0 to exit after the validation of the input file.
      89                 :             : 
      90                 :             :    real(dp) :: abimem_limit_mb = 20.0_dp
      91                 :             :     ! Optional memory limit in Mb. used when abimem_level == 3
      92                 :             : 
      93                 :             :    character(len=500) :: cmdline = ""
      94                 :             :     ! The entire command line
      95                 :             : 
      96                 :             :    character(len=fnlen) :: input_path = ""
      97                 :             : 
      98                 :             :    !! Below are for multibinit
      99                 :             :    integer :: multibinit_F03_mode = 0
     100                 :             :    !1: legacy mode
     101                 :             :    !0: use full F03 implementation mode
     102                 :             :    ! TODO: It will be deprecated when everything is ready in and the new mode will be default.
     103                 :             : 
     104                 :             :  end type args_t
     105                 :             : 
     106                 :             :  public :: args_parser   ! Parse command line options.
     107                 :             : !!***
     108                 :             : 
     109                 :             : contains
     110                 :             : 
     111                 :             : !----------------------------------------------------------------------
     112                 :             : 
     113                 :             : !!****f* m_argparse/args_parser
     114                 :             : !! NAME
     115                 :             : !!  args_parser
     116                 :             : !!
     117                 :             : !! FUNCTION
     118                 :             : !!  Simple command line argument parser for abinit and other main programs.
     119                 :             : !!
     120                 :             : !! SOURCE
     121                 :             : 
     122                 :        1663 : type(args_t) function args_parser() result(args)
     123                 :             : 
     124                 :             : !Local variables-------------------------------
     125                 :             :  integer :: ii, ierr, ntasks_per_node = -1
     126                 :             :  logical :: iam_master, verbose
     127                 :             :  real(dp) :: timelimit, memb_per_node = -one, memb_per_cpu = -one
     128                 :             :  character(len=500) :: arg !,msg
     129                 :             : 
     130                 :             : ! *************************************************************************
     131                 :             : 
     132                 :        1663 :  args%exit = 0; ierr=0; verbose = .False.
     133                 :             : 
     134                 :             : #ifndef HAVE_FC_COMMAND_ARGUMENT
     135                 :             :  call wrtout(std_out,"get_command_argument is not supported by FC. Ignoring command lines options!")
     136                 :             :  return ! Nothing to do
     137                 :             : #else
     138                 :             : 
     139         [ +  + ]:        1663 :  if (command_argument_count() == 0) return
     140                 :             : 
     141                 :        1660 :  iam_master = xmpi_comm_rank(xmpi_world) == 0
     142                 :             : 
     143                 :             :  ! Store full command line for future reference.
     144                 :        1660 :  call get_command(args%cmdline)
     145                 :             : 
     146         [ +  + ]:        3335 :  do ii=1,command_argument_count()
     147                 :        1675 :    call get_command_argument(ii, arg)
     148                 :             :    !write(std_out,*)"arg", trim(arg)
     149                 :             : 
     150   [ +  +  +  + ]:        1675 :    if (ii == 1 .and. .not. firstchar(arg, "-")) then
     151                 :             :      ! `abinit path` syntax reads input from path and deactivates files file mode.
     152                 :        1659 :      args%input_path = trim(arg)
     153         [ +  + ]:        1659 :      if (iam_master) then
     154         [ -  + ]:        1354 :         ABI_CHECK(file_exists(args%input_path), sjoin("Cannot find input file:", args%input_path))
     155                 :             :      end if
     156                 :             :      cycle
     157                 :             :    end if
     158                 :             : 
     159   [ +  -  -  + ]:        1676 :    if (arg == "-v" .or. arg == "--version") then
     160                 :           0 :      call wrtout(std_out, trim(abinit_version))
     161                 :           0 :      args%exit = args%exit + 1
     162                 :             : 
     163   [ +  +  -  + ]:          16 :    else if (arg == "-b" .or. arg == "--build") then
     164                 :           1 :      call print_kinds(unit=std_out)
     165                 :           1 :      call xmpi_show_info(unit=std_out)
     166                 :           1 :      call dump_cpp_options(std_out)
     167                 :           1 :      call dump_config(std_out)
     168                 :           1 :      call dump_optim(std_out)
     169                 :             : 
     170                 :           1 :      args%exit = args%exit + 1
     171                 :             : 
     172   [ +  -  +  + ]:          15 :    else if (arg == "-d" .or. arg == "--dry-run") then
     173                 :           1 :      args%dry_run = 1
     174                 :             : 
     175         [ -  + ]:          14 :    else if (arg == "--abimem-level") then
     176                 :           0 :      call get_command_argument(ii + 1, arg)
     177                 :           0 :      args%abimem_level = atoi(arg)
     178                 :             : 
     179         [ -  + ]:          14 :    else if (arg == "--abimem-limit-mb") then
     180                 :           0 :      call get_command_argument(ii + 1, arg)
     181                 :           0 :      args%abimem_limit_mb = atof(arg)
     182                 :             : 
     183   [ +  -  -  + ]:          14 :    else if (arg == "-j" .or. arg == "--omp-num-threads") then
     184                 :           0 :      call get_command_argument(ii + 1, arg)
     185                 :           0 :      call xomp_set_num_threads(atoi(arg))
     186                 :             : 
     187   [ +  -  +  + ]:          14 :    else if (arg == "-t" .or. arg == "--timelimit") then
     188                 :             :      ! timelimit handler.
     189                 :           4 :      call get_command_argument(ii + 1, arg)
     190                 :           4 :      timelimit = str2sec(arg)
     191         [ -  + ]:           4 :      if (timelimit < zero) then
     192                 :           0 :        write(std_out,*)"Wrong timelimit argument: ",trim(arg)
     193                 :           0 :        args%exit = args%exit + 1
     194                 :             :      else
     195                 :           4 :        call exit_init(timelimit)
     196                 :             :      end if
     197                 :             : 
     198         [ -  + ]:          10 :    else if (arg == "--ieee-halt") then
     199                 :             :      ! IEEE exceptions.
     200                 :           0 :      call xieee_halt_ifexc(.True.)
     201                 :             : 
     202         [ -  + ]:          10 :    else if (arg == "--ieee-signal") then
     203                 :           0 :      call xieee_signal_ifexc(.True.)
     204                 :             : 
     205                 :          10 :    else if (begins_with(arg, "--fft-ialltoall")) then
     206                 :             :      ! Enable/disable non-blocking ialltoall in MPI-FFT
     207                 :           0 :      call fft_allow_ialltoall(parse_yesno(arg, "--fft-ialltoall"))
     208                 :             : 
     209                 :          10 :    else if (begins_with(arg, "--ipi")) then
     210                 :           0 :      call get_command_argument(ii + 1, arg)
     211                 :           0 :      call ipi_setup(arg, xmpi_world)
     212                 :             : 
     213                 :          10 :    else if (begins_with(arg, "--use-xgemm3m")) then
     214                 :             :      ! Enable/disable [Z,C]GEMM3
     215                 :           0 :      call linalg_allow_gemm3m(parse_yesno(arg, "--use-xgemm3m"), write_msg=iam_master)
     216                 :             : 
     217                 :          10 :    else if (begins_with(arg, "--use-mpi-in-place")) then
     218                 :             :      ! Enable/disable usage of MPI_IN_PLACE.
     219                 :           0 :      call xmpi_set_inplace_operations(parse_yesno(arg, "--use-mpi-in-place"))
     220                 :             : 
     221                 :          10 :    else if (begins_with(arg, "--plasma")) then
     222                 :             :      ! Enable/disable PLASMA
     223                 :           0 :      call linalg_allow_plasma(parse_yesno(arg, "--plasma"))
     224                 :             : 
     225         [ -  + ]:          10 :    else if (arg == "--gnu-mtrace") then
     226         [ #  # ]:           0 :      if (iam_master) then
     227                 :           0 :        call clib_mtrace(ierr)
     228         [ #  # ]:           0 :        ABI_CHECK(ierr == 0, sjoin("clib_mtrace returned ierr:", itoa(ierr)))
     229                 :             :      end if
     230                 :             : 
     231         [ -  + ]:          10 :    else if (arg == "--log") then
     232                 :             :      ! Enable logging
     233                 :           0 :      call abi_log_status_state(new_do_write_log=.True., new_do_write_status=.True.)
     234                 :           0 :      call libpaw_log_flag_set(.True.)
     235                 :             : 
     236         [ -  + ]:          10 :    else if (arg == "--netcdf-classic") then
     237                 :             :      ! Use netcdf classic mode for new files when only sequential-IO needs to be performed
     238                 :           0 :      call nctk_use_classic_for_seq()
     239                 :             : 
     240         [ -  + ]:          10 :    else if (arg == "--enforce-fortran-io") then
     241                 :           0 :      call enforce_fortran_io(.True.)
     242                 :             : 
     243                 :          10 :    else if (begins_with(arg, "--mem-per-cpu=")) then
     244                 :           0 :      memb_per_cpu = parse_slurm_mem(arg, "--mem-per-cpu=")
     245                 :           0 :      call set_mem_per_cpu_mb(memb_per_cpu)
     246                 :             : 
     247                 :          10 :    else if (begins_with(arg, "--mem=")) then
     248                 :           0 :      memb_per_node = parse_slurm_mem(arg, "--mem=")
     249                 :             : 
     250                 :          10 :    else if (begins_with(arg, "--ntasks-per-node=")) then
     251                 :           0 :      call get_command_argument(ii + 1, arg)
     252                 :           0 :      ntasks_per_node = atoi(arg)
     253                 :             : 
     254         [ +  + ]:          10 :    else if (arg == "--F03") then
     255                 :             :      ! For multibinit only
     256                 :           6 :      args%multibinit_F03_mode = 1
     257                 :             : 
     258   [ +  -  -  + ]:           4 :    else if (arg == "-h" .or. arg == "--help") then
     259         [ #  # ]:           0 :      if (iam_master) then
     260                 :             :        ! Document the options.
     261                 :           0 :        write(std_out,*)"-v, --version              Show version number and exit."
     262                 :           0 :        write(std_out,*)"-b, --build                Show build parameters and exit."
     263                 :           0 :        write(std_out,*)"-d, --dry-run              Validate input file and exit."
     264                 :           0 :        write(std_out,*)"-j, --omp-num-threads      Set the number of OpenMp threads."
     265                 :           0 :        write(std_out,*)"--use-xgemm3m[=yesno]      Use ZGEMM3M routines instead of ZGEMM. Default: no "
     266                 :           0 :        write(std_out,*)"--use-mpi-in-place[=yesno] Enable/disable usage of MPI_IN_PLACE in e.g. xmpi_sum. Default: no"
     267                 :           0 :        write(std_out,*)"                           Note that some MPI libs e.g. intel-mpi may not implement this feature"
     268                 :           0 :        write(std_out,*)"                           correctly so it is adviced to test this option with e.g. structural"
     269                 :           0 :        write(std_out,*)"                           relaxations before running production calculations."
     270                 :           0 :        write(std_out,*)"--ipi                      Activate socket-driven calculation using i-pi protocol."
     271                 :           0 :        write(std_out,*)"                           For UNIX socket, use: --ipi {unixsocket}:UNIX"
     272                 :           0 :        write(std_out,*)"                           For INET socket, use  --ipi {host}:{port}. Usage example:"
     273                 :           0 :        write(std_out,*)"                           `abinit run.abi --ipi {unixsocket}:UNIX > run.log`"
     274                 :           0 :        write(std_out,*)"                           NB: Requires ionmov 28 and some tuning of input variables. See:"
     275                 :           0 :        write(std_out,*)"                           https://wiki.fysik.dtu.dk/ase/dev/ase/calculators/socketio/socketio.html"
     276                 :           0 :        write(std_out,*)"--log                      Enable log files and status files in parallel execution."
     277                 :           0 :        write(std_out,*)"--netcdf-classic           Use netcdf classic mode for new files if parallel-IO is not needed."
     278                 :           0 :        write(std_out,*)"                           Default is netcdf4/hdf5"
     279                 :           0 :        write(std_out,*)"--enforce-fortran-io       Use Fortran-IO instead of MPI-IO when operating on Fortran files"
     280                 :           0 :        write(std_out,*)"                           Useful to read files when the MPI-IO library is not efficient."
     281                 :           0 :        write(std_out,*)"                           DON'T USE this option when the code needs to write large files e.g. WFK"
     282                 :           0 :        write(std_out,*)"-t, --timelimit            Set the timelimit for the run. Accepts time in Slurm syntax:"
     283                 :           0 :        write(std_out,*)"                               days-hours"
     284                 :           0 :        write(std_out,*)"                               days-hours:minutes"
     285                 :           0 :        write(std_out,*)"                               days-hours:minutes:seconds"
     286                 :           0 :        write(std_out,*)"                               minutes"
     287                 :           0 :        write(std_out,*)"                               minutes:seconds"
     288                 :           0 :        write(std_out,*)"                               hours:minutes:seconds"
     289                 :           0 :        write(std_out,*)"                           At present only GS, relaxations and MD runs support this option"
     290                 :           0 :        write(std_out,*)"--mem-per-cpu=<size>[units] Set memory per cpu using Slurm syntax. Default units are megabytes."
     291                 :           0 :        write(std_out,*)"                           Different units can be specified using the suffix [K|M|G|T]."
     292                 :           0 :        write(std_out,*)"--mem=<size>[units]        Set memory per node using Slurm syntax. Default units are megabytes."
     293                 :           0 :        write(std_out,*)"                           Requires `ntasks-per-node`. Not compatibile with `-mem-per-cpu`."
     294                 :           0 :        write(std_out,*)"--ntasks-per-node=INT      Set number of tasks per node. Used in conjunction with --mem`"
     295                 :           0 :        write(std_out,*)"--verbose                  Enable verbose mode in argparse"
     296                 :           0 :        write(std_out,*)"-h, --help                 Show this help and exit."
     297                 :             : 
     298                 :           0 :        write(std_out,*)""
     299                 :           0 :        write(std_out,*)""
     300                 :           0 :        write(std_out,*)"=============================="
     301                 :           0 :        write(std_out,*)"=== Options for developers ==="
     302                 :           0 :        write(std_out,*)"=============================="
     303                 :           0 :        write(std_out,*)"--abimem-level NUM         Set memory profiling level. Requires HAVE_MEM_PROFILING in config.h"
     304                 :           0 :        write(std_out,*)"       0 -> no file abimem.mocc is created, only memory allocation counters running."
     305                 :           0 :        write(std_out,*)"       1 -> light version. Only memory peaks are written."
     306                 :           0 :        write(std_out,*)"       2 -> file abimem.mocc is created with full information inside."
     307                 :           0 :        write(std_out,*)"       3 -> Write info only if allocation/deallocation is larger or smaller than limit_mb"
     308                 :           0 :        write(std_out,*)"            depending on of the sign of abimem-limit-mb."
     309                 :           0 :        write(std_out,*)"    NOTE: By default, only master node writes, use negative values to make all MPI procs write info to disk."
     310                 :           0 :        write(std_out,*)"--abimem-limit-mb NUM      Log malloc/free only if size > limit in Megabytes. Requires abimem-level 3"
     311                 :           0 :        write(std_out,*)"--fft-ialltoall[=yesno]    Use non-blocking ialltoall in MPI-FFT (used only if ndat > 1 and MPI2+)."
     312                 :           0 :        write(std_out,*)"--gnu-mtrace               Enable mtrace (requires GNU and clib)."
     313                 :           0 :        write(std_out,*)"--ieee-halt                Halt the code if one of the *usual* IEEE exceptions is raised."
     314                 :           0 :        write(std_out,*)"--ieee-signal              Signal the occurrence of the *usual* IEEE exceptions."
     315                 :             :        ! Multibinit
     316                 :           0 :        write(std_out,*)"--F03                      Run F03 mode (Multibinit only)."
     317                 :             :      end if
     318                 :           0 :      args%exit = args%exit + 1
     319                 :             : 
     320         [ +  - ]:           4 :    else if (arg == "--verbose") then
     321                 :        1675 :      verbose = .True.
     322                 :             : 
     323                 :             :    else
     324         [ -  + ]:           4 :      if (firstchar(arg, "-")) then
     325         [ #  # ]:           0 :        ABI_WARNING("Unsupported option: "//trim(arg))
     326                 :           0 :        args%exit = args%exit + 1
     327                 :             :      else
     328                 :             :        continue
     329                 :             :      end if
     330                 :             :    end if
     331                 :             :  end do
     332                 :             : 
     333   [ +  -  -  + ]:        1660 :  if (ntasks_per_node /= -1 .or. memb_per_node /= -one) then
     334                 :             :    ! Set mem_per_cpu from node info.
     335         [ #  # ]:           0 :    ABI_CHECK(ntasks_per_node /= -1, "`mem-per-node` requires `ntasks-per-node`")
     336         [ #  # ]:           0 :    ABI_CHECK(memb_per_node /= -one, "`ntasks-per-node` requires `mem-per-node`")
     337         [ #  # ]:           0 :    ABI_CHECK(memb_per_cpu == -one, "`mem-per-cpu` and `mem-per-node` are mutually exclusive!")
     338                 :           0 :    call set_mem_per_cpu_mb(memb_per_node / ntasks_per_node)
     339                 :             :  end if
     340                 :             : 
     341                 :             : #endif
     342                 :             : 
     343                 :        3323 : end function args_parser
     344                 :             : !!***
     345                 :             : 
     346                 :             : !!****f* m_argparse/begins_with
     347                 :             : !! NAME
     348                 :             : !!  begins_with
     349                 :             : !!
     350                 :             : !! FUNCTION
     351                 :             : !!  Returns true if argument arg begins with string
     352                 :             : !!
     353                 :             : !! SOURCE
     354                 :             : 
     355                 :          80 : pure logical function begins_with(arg, string) result(bool)
     356                 :             : 
     357                 :             : !Arguments ------------------------------------
     358                 :             :  character(len=*),intent(in) :: arg,string
     359                 :             : ! *************************************************************************
     360                 :             : 
     361   [ -  +  -  +  :          20 :  bool = .False.; if (len(arg) >= len(string)) bool = (arg(1:len(string)) == string)
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  - ]
     362                 :             : 
     363                 :           0 : end function begins_with
     364                 :             : !!***
     365                 :             : 
     366                 :             : !----------------------------------------------------------------------
     367                 :             : 
     368                 :             : !!****f* m_argparse/parse_yesno
     369                 :             : !! NAME
     370                 :             : !!  parse_yesno
     371                 :             : !!
     372                 :             : !! FUNCTION
     373                 :             : !!  This function receives an argument, arg of the form --foo[=bool_value]
     374                 :             : !!  that begins with optname (i.e. --foo) and returns the value of bool_value
     375                 :             : !!  If bool_value is not present, returns default (.True. if not specified)
     376                 :             : !!
     377                 :             : !! SOURCE
     378                 :             : 
     379                 :           0 : logical function parse_yesno(arg, optname, default) result(bool)
     380                 :             : 
     381                 :             : !Arguments ------------------------------------
     382                 :             :  character(len=*),intent(in) :: arg,optname
     383                 :             :  logical,optional,intent(in) :: default
     384                 :             : ! *************************************************************************
     385                 :             : 
     386         [ #  # ]:           0 :  bool = .True.; if (present(default)) bool = default
     387                 :             : 
     388                 :             :  ! Assume default if value is not given
     389         [ #  # ]:           0 :  if (len_trim(optname) == len_trim(arg)) return
     390                 :             : 
     391                 :           0 :  select case (arg(len(optname)+1:))
     392                 :             :  case ("=yes", "=y")
     393                 :           0 :    bool = .True.
     394                 :             :  case ("=no", "=n")
     395                 :           0 :    bool = .False.
     396                 :             :  case default
     397                 :           0 :    write(std_out,*)"Wrong option ",trim(arg),". Will default to ",bool
     398      [ #  #  # ]:           0 :    ABI_ERROR("Aborting now")
     399                 :             :  end select
     400                 :             : 
     401                 :           0 : end function parse_yesno
     402                 :             : !!***
     403                 :             : 
     404                 :             : !----------------------------------------------------------------------
     405                 :             : 
     406                 :             : !!****f* m_argparse/parse_slurm_mem
     407                 :             : !! NAME
     408                 :             : !!  parse_slurm_mem
     409                 :             : !!
     410                 :             : !! FUNCTION
     411                 :             : !!  Parse `arg` string with memory given in Slurm syntax. Return value in Mb.
     412                 :             : !!  From https://slurm.schedmd.com/sbatch.html
     413                 :             : !!
     414                 :             : !!  --mem=<size>[units]
     415                 :             : !!
     416                 :             : !!  Default units are megabytes. Different units can be specified using the suffix [K|M|G|T].
     417                 :             : !!
     418                 :             : !!  For a list of slurm env variables that can be used to pass options to Abinit via the submission script, see:
     419                 :             : !!  https://docs.hpc.shef.ac.uk/en/latest/referenceinfo/scheduler/SLURM/SLURM-environment-variables.html
     420                 :             : !!
     421                 :             : !! SOURCE
     422                 :             : 
     423                 :           0 : real(dp) function parse_slurm_mem(arg, optname) result(mem_mb)
     424                 :             : 
     425                 :             : !Arguments ------------------------------------
     426                 :             :  character(len=*),intent(in) :: arg,optname
     427                 :             : 
     428                 :             : !Local variables-------------------------------
     429                 :             :  integer :: istop, istat
     430                 :             :  real(dp) :: fact
     431                 :             :  character(len=500) :: iomsg
     432                 :             : ! *************************************************************************
     433                 :             : 
     434                 :             :  fact = one
     435                 :             :  istop = find_and_select(arg, &
     436                 :             :                          ["K", "M", "G", "T"], &
     437         [ #  # ]:           0 :                          [one/1024._dp, one, 1024._dp, 1024._dp ** 2], fact, iomsg, default=one)
     438                 :             : 
     439         [ #  # ]:           0 :  ABI_CHECK(istop /= -1, iomsg)
     440         [ #  # ]:           0 :  istop = merge(len_trim(arg), istop - 1, istop == 0)
     441                 :             : 
     442                 :           0 :  read(arg(len(optname) + 1: istop), *, iostat=istat, iomsg=iomsg) mem_mb
     443         [ #  # ]:           0 :  ABI_CHECK(istat == 0, sjoin("Invalid syntax for memory string:", arg, ch10, "iomsg", iomsg))
     444         [ #  # ]:           0 :  ABI_CHECK(mem_mb > zero, "mem_mb must be positive!")
     445                 :           0 :  mem_mb = mem_mb * fact
     446                 :             : 
     447                 :           0 : end function parse_slurm_mem
     448                 :             : !!***
     449                 :             : 
     450                 :             : !----------------------------------------------------------------------
     451                 :             : 
     452                 :             : !!****f* m_argparse/get_arg_int
     453                 :             : !! NAME
     454                 :             : !!  get_arg_int
     455                 :             : !!
     456                 :             : !! FUNCTION
     457                 :             : !!  Parse scalar argument from command line. Return exit code.
     458                 :             : !!
     459                 :             : !! INPUT
     460                 :             : !!  argname= Argument name
     461                 :             : !!  [default]= Default value.
     462                 :             : !!  [exclude]= argname and exclude are mutually exclusive.
     463                 :             : !!
     464                 :             : !! OUTPUT
     465                 :             : !!  argval= Value of argname
     466                 :             : !!  msg= Error message
     467                 :             : !!
     468                 :             : !! SOURCE
     469                 :             : 
     470                 :          65 : integer function get_arg_int(argname, argval, msg, default, exclude) result(ierr)
     471                 :             : 
     472                 :             : !Arguments ------------------------------------
     473                 :             : !scalars
     474                 :             :  character(len=*),intent(in) :: argname
     475                 :             :  integer,intent(out) :: argval
     476                 :             :  character(len=*),intent(out) :: msg
     477                 :             :  integer,optional,intent(in) :: default
     478                 :             :  character(len=*),optional,intent(in) :: exclude
     479                 :             : 
     480                 :             : !Local variables-------------------------------
     481                 :             :  integer :: ii, istat
     482                 :             :  logical :: found_argname, found_excl
     483                 :             :  character(len=500) :: arg, iomsg
     484                 :             : 
     485                 :             : ! *************************************************************************
     486                 :             : 
     487         [ +  - ]:          65 :  ierr = 0; msg = ""; if (present(default)) argval = default
     488                 :          65 :  found_argname = .False.; found_excl = .False.
     489                 :             : 
     490         [ +  + ]:          83 :  do ii=1,command_argument_count()
     491                 :          18 :    call get_command_argument(ii, arg)
     492         [ +  - ]:          18 :    if (present(exclude)) then
     493         [ #  # ]:           0 :      if (arg == "--" // trim(exclude)) found_excl = .True.
     494                 :             :    end if
     495         [ -  + ]:          83 :    if (arg == "--" // trim(argname)) then
     496                 :           0 :      found_argname = .True.
     497                 :           0 :      call get_command_argument(ii + 1, arg, status=istat)
     498         [ #  # ]:           0 :      if (istat == 0) then
     499                 :           0 :        read(arg, *, iostat=istat, iomsg=iomsg) argval
     500         [ #  # ]:           0 :        if (istat /= 0) then
     501   [ #  #  #  # ]:           0 :          ierr = ierr + 1; msg = sjoin(msg, ch10, iomsg)
     502                 :             :        end if
     503                 :             :      else
     504   [ #  #  #  # ]:           0 :        ierr = ierr + 1; msg = sjoin(msg, ch10, "Error in get_command_argument")
     505                 :             :      end if
     506                 :             :    end if
     507                 :             :  end do
     508                 :             : 
     509   [ -  +  -  -  :          65 :  if (ierr /= 0) msg = sjoin("Error while reading argument: ", argname, ch10, msg)
                   -  - ]
     510         [ -  + ]:          65 :  if (found_argname .and. found_excl) then
     511   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = sjoin("Variables", argname, "and", exclude, "are mutually exclusive", ch10, msg)
     512                 :             :  end if
     513                 :             : 
     514         [ +  - ]:          65 : end function get_arg_int
     515                 :             : !!***
     516                 :             : 
     517                 :             : !!****f* m_argparse/get_arg_dp
     518                 :             : !! NAME
     519                 :             : !!  get_arg_dp
     520                 :             : !!
     521                 :             : !! FUNCTION
     522                 :             : !!  Parse scalar argument from command line. Return exit code.
     523                 :             : !!
     524                 :             : !! INPUTS
     525                 :             : !!  argname= Argument name
     526                 :             : !!  [default]= Default value
     527                 :             : !!  [exclude]= argname and exclude are mutually exclusive.
     528                 :             : !!
     529                 :             : !! OUTPUT
     530                 :             : !!   argval= Value of argname
     531                 :             : !!   msg= Error message
     532                 :             : !!
     533                 :             : !! SOURCE
     534                 :             : 
     535                 :          44 : integer function get_arg_dp(argname, argval, msg, default, exclude) result(ierr)
     536                 :             : 
     537                 :             : !Arguments ------------------------------------
     538                 :             : !scalars
     539                 :             :  character(len=*),intent(in) :: argname
     540                 :             :  real(dp),intent(out) :: argval
     541                 :             :  character(len=*),intent(out) :: msg
     542                 :             :  real(dp),optional,intent(in) :: default
     543                 :             :  character(len=*),optional,intent(in) :: exclude
     544                 :             : 
     545                 :             : !Local variables-------------------------------
     546                 :             :  integer :: ii, istat
     547                 :             :  logical :: found_argname, found_excl
     548                 :             :  character(len=500) :: arg, iomsg
     549                 :             : 
     550                 :             : ! *************************************************************************
     551                 :             : 
     552         [ +  - ]:          44 :  ierr = 0; msg = ""; if (present(default)) argval = default
     553                 :          44 :  found_argname = .False.; found_excl = .False.
     554                 :             : 
     555         [ -  + ]:          44 :  do ii=1,command_argument_count()
     556                 :           0 :    call get_command_argument(ii, arg)
     557         [ #  # ]:           0 :    if (present(exclude)) then
     558         [ #  # ]:           0 :      if (arg == "--" // trim(exclude)) found_excl = .True.
     559                 :             :    end if
     560         [ -  - ]:          44 :    if (arg == "--" // trim(argname)) then
     561                 :           0 :      found_argname = .True.
     562                 :           0 :      call get_command_argument(ii + 1, arg, status=istat)
     563         [ #  # ]:           0 :      if (istat == 0) then
     564                 :           0 :        read(arg, *, iostat=istat, iomsg=iomsg) argval
     565         [ #  # ]:           0 :        if (istat /= 0) then
     566   [ #  #  #  # ]:           0 :          ierr = ierr + 1; msg = sjoin(msg, ch10, iomsg)
     567                 :             :        end if
     568                 :             :      else
     569   [ #  #  #  # ]:           0 :        ierr = ierr + 1; msg = sjoin(msg, ch10, "Error in get_command_argument")
     570                 :             :      end if
     571                 :             :    end if
     572                 :             :  end do
     573                 :             : 
     574   [ -  +  -  -  :          44 :  if (ierr /= 0) msg = sjoin("Error while reading argument: ", argname, ch10, msg)
                   -  - ]
     575         [ -  + ]:          44 :  if (found_argname .and. found_excl) then
     576   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = sjoin("Variables", argname, "and", exclude, "are mutually exclusive", ch10, msg)
     577                 :             :  end if
     578                 :             : 
     579         [ +  - ]:          44 : end function get_arg_dp
     580                 :             : !!***
     581                 :             : 
     582                 :             : !----------------------------------------------------------------------
     583                 :             : 
     584                 :             : !!****f* m_argparse/get_arg_str
     585                 :             : !! NAME
     586                 :             : !!  get_arg_str
     587                 :             : !!
     588                 :             : !! FUNCTION
     589                 :             : !!  Parse scalar string argument from command line. Return exit code.
     590                 :             : !!
     591                 :             : !! INPUTS
     592                 :             : !!  argname= Argument name
     593                 :             : !!  [default]= Default value
     594                 :             : !!  [exclude]= argname and exclude are mutually exclusive.
     595                 :             : !!
     596                 :             : !! OUTPUT
     597                 :             : !!   argval= Value of argname
     598                 :             : !!   msg= Error message
     599                 :             : !!
     600                 :             : !! SOURCE
     601                 :             : 
     602                 :           0 : integer function get_arg_str(argname, argval, msg, default, exclude) result(ierr)
     603                 :             : 
     604                 :             : !Arguments ------------------------------------
     605                 :             : !scalars
     606                 :             :  character(len=*),intent(in) :: argname
     607                 :             :  character(len=*),intent(out) :: argval, msg
     608                 :             :  character(len=*),optional,intent(in) :: default
     609                 :             :  character(len=*),optional,intent(in) :: exclude
     610                 :             : 
     611                 :             : !Local variables-------------------------------
     612                 :             :  integer :: ii, istat
     613                 :             :  logical :: found_argname, found_excl
     614                 :             :  character(len=500) :: arg
     615                 :             : 
     616                 :             : ! *************************************************************************
     617                 :             : 
     618   [ #  #  #  #  :           0 :  ierr = 0; msg = ""; if (present(default)) argval = default
                   #  # ]
     619                 :           0 :  found_argname = .False.; found_excl = .False.
     620                 :             : 
     621         [ #  # ]:           0 :  do ii=1,command_argument_count()
     622                 :           0 :    call get_command_argument(ii, arg)
     623         [ #  # ]:           0 :    if (present(exclude)) then
     624         [ #  # ]:           0 :      if (arg == "--" // trim(exclude)) found_excl = .True.
     625                 :             :    end if
     626         [ #  # ]:           0 :    if (arg == "--" // trim(argname)) then
     627                 :           0 :      found_argname = .True.
     628                 :           0 :      call get_command_argument(ii + 1, argval, status=istat)
     629         [ #  # ]:           0 :      if (istat /= 0) then
     630   [ #  #  #  # ]:           0 :        ierr = ierr + 1; msg = sjoin(msg, ch10, "Error in get_command_argument")
     631                 :             :      end if
     632                 :             :    end if
     633                 :             :  end do
     634                 :             : 
     635   [ #  #  #  #  :           0 :  if (ierr /= 0) msg = sjoin("Error while reading argument: ", argname, ch10, msg)
                   #  # ]
     636         [ #  # ]:           0 :  if (found_argname .and. found_excl) then
     637   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = sjoin("Variables", argname, "and", exclude, "are mutually exclusive", ch10, msg)
     638                 :             :  end if
     639                 :             : 
     640         [ #  # ]:           0 : end function get_arg_str
     641                 :             : !!***
     642                 :             : 
     643                 :             : !----------------------------------------------------------------------
     644                 :             : 
     645                 :             : !!****f* m_argparse/get_arg_bool
     646                 :             : !! NAME
     647                 :             : !!  get_arg_bool
     648                 :             : !!
     649                 :             : !! FUNCTION
     650                 :             : !!  Parse scalar boolean argument from command line. Return exit code.
     651                 :             : !!
     652                 :             : !! INPUTS
     653                 :             : !!  argname= Argument name
     654                 :             : !!  [default]= Default value
     655                 :             : !!  [exclude]= argname and exclude are mutually exclusive.
     656                 :             : !!
     657                 :             : !! OUTPUT
     658                 :             : !!   argval= Value of argname
     659                 :             : !!   msg= Error message
     660                 :             : !!
     661                 :             : !! SOURCE
     662                 :             : 
     663                 :           0 : integer function get_arg_bool(argname, argval, msg, default, exclude) result(ierr)
     664                 :             : 
     665                 :             : !Arguments ------------------------------------
     666                 :             : !scalars
     667                 :             :  character(len=*),intent(in) :: argname
     668                 :             :  logical,intent(out) :: argval
     669                 :             :  character(len=*),intent(out) :: msg
     670                 :             :  logical,optional,intent(in) :: default
     671                 :             :  character(len=*),optional,intent(in) :: exclude
     672                 :             : 
     673                 :             : !Local variables-------------------------------
     674                 :             :  integer :: ii
     675                 :             :  logical :: found_argname, found_excl
     676                 :             :  character(len=500) :: arg
     677                 :             : 
     678                 :             : ! *************************************************************************
     679                 :             : 
     680                 :           0 :  ierr = 0; msg = ""; if (present(default)) argval = default
     681                 :           0 :  found_argname = .False.; found_excl = .False.
     682                 :           0 :  argval = .False.
     683                 :             : 
     684         [ #  # ]:           0 :  do ii=1,command_argument_count()
     685                 :           0 :    call get_command_argument(ii, arg)
     686         [ #  # ]:           0 :    if (present(exclude)) then
     687         [ #  # ]:           0 :      if (arg == "--" // trim(exclude)) found_excl = .True.
     688                 :             :    end if
     689         [ #  # ]:           0 :    if (begins_with(arg, "--" // trim(argname))) then
     690                 :           0 :      argval = parse_yesno(arg, "--" // trim(argname), default=.True.)
     691                 :           0 :      found_argname = .True.
     692                 :             :    end if
     693                 :             :  end do
     694                 :             : 
     695                 :             :  if (ierr /= 0) msg = sjoin("Error while reading argument: ", argname, ch10, msg)
     696         [ #  # ]:           0 :  if (found_argname .and. found_excl) then
     697   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = sjoin("Variables", argname, "and", exclude, "are mutually exclusive", ch10, msg)
     698                 :             :  end if
     699                 :             : 
     700         [ #  # ]:           0 : end function get_arg_bool
     701                 :             : !!***
     702                 :             : 
     703                 :             : !----------------------------------------------------------------------
     704                 :             : 
     705                 :             : !!****f* m_argparse/get_start_step_num
     706                 :             : !! NAME
     707                 :             : !!  get_start_step_num
     708                 :             : !!
     709                 :             : !! FUNCTION
     710                 :             : !!  Parse string from command line in the format "start:step:num" defining an arithmetic progression.
     711                 :             : !!  Return exit code.
     712                 :             : !!
     713                 :             : !! INPUTS
     714                 :             : !!  argname= Argument name
     715                 :             : !!  [default]= Default value
     716                 :             : !!  [exclude]= argname and exclude are mutually exclusive.
     717                 :             : !!
     718                 :             : !! OUTPUT
     719                 :             : !!   ilist= [start, step, num]
     720                 :             : !!   msg= Error message
     721                 :             : !!
     722                 :             : !! SOURCE
     723                 :             : 
     724                 :           0 : integer function get_start_step_num(argname, ilist, msg, default, exclude) result(ierr)
     725                 :             : 
     726                 :             : !Arguments ------------------------------------
     727                 :             : !scalars
     728                 :             :  character(len=*),intent(in) :: argname
     729                 :             :  integer,intent(out) :: ilist(3)
     730                 :             :  character(len=*),intent(out) :: msg
     731                 :             :  integer,optional,intent(in) :: default(3)
     732                 :             :  character(len=*),optional,intent(in) :: exclude
     733                 :             : 
     734                 :             : !Local variables-------------------------------
     735                 :             :  integer :: ii, jj
     736                 :             :  character(len=500) :: str
     737                 :             : 
     738                 :             : ! *************************************************************************
     739                 :             : 
     740                 :           0 :  if (present(exclude)) then
     741                 :           0 :    ierr = get_arg_str(argname, str, msg, default="", exclude=exclude)
     742                 :             :  else
     743                 :           0 :    ierr = get_arg_str(argname, str, msg, default="")
     744                 :             :  end if
     745         [ #  # ]:           0 :  if (ierr /= 0) return
     746                 :             : 
     747         [ #  # ]:           0 :  if (len_trim(str) == 0) then
     748         [ #  # ]:           0 :    if (present(default)) then
     749                 :           0 :      ilist = default
     750                 :             :    else
     751   [ #  #  #  # ]:           0 :      ierr = ierr + 1; msg = sjoin("Variables", argname, "is not found and default is not given")
     752                 :             :    end if
     753                 :           0 :    return
     754                 :             :  end if
     755                 :             : 
     756                 :             :  ! We got a non-empty string. Let's parse it.
     757                 :           0 :  ii = index(str, ":")
     758         [ #  # ]:           0 :  if (ii <= 1) then
     759   [ #  #  #  # ]:           0 :    msg = sjoin("Cannot find first `:` in string:", str)
     760                 :           0 :    ierr = ierr + 1; return
     761                 :             :  end if
     762                 :           0 :  ilist(1) = atoi(str(1:ii-1))
     763                 :             : 
     764                 :           0 :  jj = index(str(ii+1:), ":")
     765         [ #  # ]:           0 :  if (jj == 0) then
     766   [ #  #  #  # ]:           0 :    msg = sjoin("Cannot find second `:` in string:", str)
     767                 :           0 :    ierr = ierr + 1; return
     768                 :             :  end if
     769                 :             : 
     770                 :           0 :  ilist(2) = atoi(str(ii+1: jj+ii-1))
     771                 :           0 :  ilist(3) = atoi(str(jj+ii+1:))
     772                 :             :  !print *, "ilist:", ilist
     773                 :             : 
     774         [ #  # ]:           0 : end function get_start_step_num
     775                 :             : !!***
     776                 :             : 
     777                 :             : !!****f* m_argparse/get_arg_list_int
     778                 :             : !! NAME
     779                 :             : !!  get_arg_list_int
     780                 :             : !!
     781                 :             : !! FUNCTION
     782                 :             : !!  Parse array argument from command line. Return exit code.
     783                 :             : !!
     784                 :             : !! INPUT
     785                 :             : !!  argname= Argument name
     786                 :             : !!  [default]= Default value (scalar)
     787                 :             : !!  [default_list]= Default value (vector)
     788                 :             : !!  [exclude]= argname and exclude are mutually exclusive.
     789                 :             : !!  [want_len]= Require want_len items in CLI.
     790                 :             : !!
     791                 :             : !! OUTPUT
     792                 :             : !!  argval= Value of argname
     793                 :             : !!  msg= Error message
     794                 :             : !!
     795                 :             : !! SOURCE
     796                 :             : 
     797   [ #  #  #  #  :           0 : integer function get_arg_list_int(argname, argval, lenr, msg, default, default_list, exclude, want_len) result(ierr)
                   #  # ]
     798                 :             : 
     799                 :             : !Arguments ------------------------------------
     800                 :             : !scalars
     801                 :             :  character(len=*),intent(in) :: argname
     802                 :             :  integer,intent(out) :: argval(:)
     803                 :             :  integer,intent(out) :: lenr
     804                 :             :  character(len=*),intent(out) :: msg
     805                 :             :  character(len=*),optional,intent(in) :: exclude
     806                 :             :  integer,optional,intent(in) :: default
     807                 :             :  integer,optional,intent(in) :: default_list(:)
     808                 :             :  integer,optional,intent(in) :: want_len
     809                 :             : 
     810                 :             : !Local variables-------------------------------
     811                 :             :  integer :: ii, istat, iarg, maxlen
     812                 :             :  logical :: found_argname, found_excl
     813                 :             :  character(len=500) :: arg, iomsg
     814                 :             : 
     815                 :             : ! *************************************************************************
     816                 :             : 
     817         [ #  # ]:           0 :  ierr = 0; msg = ""; lenr = 0
     818                 :           0 :  found_argname = .False.; found_excl = .False.
     819                 :             : 
     820                 :           0 :  maxlen = size(argval);
     821         [ #  # ]:           0 :  if (maxlen == 0) then
     822   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = "zero-sized argval!"; return
     823                 :             :  end if
     824                 :             : 
     825   [ #  #  #  # ]:           0 :  if (present(default)) argval = default
     826   [ #  #  #  # ]:           0 :  if (present(default_list)) argval = default_list
     827                 :             : 
     828         [ #  # ]:           0 :  do ii=1,command_argument_count()
     829                 :           0 :    call get_command_argument(ii, arg)
     830         [ #  # ]:           0 :    if (present(exclude)) then
     831         [ #  # ]:           0 :      if (arg == "--" // trim(exclude)) found_excl = .True.
     832                 :             :    end if
     833         [ #  # ]:           0 :    if (arg == "--" // trim(argname)) then
     834                 :             :      ! Read list of values
     835                 :           0 :      found_argname = .True.
     836         [ #  # ]:           0 :      do iarg=1,maxlen
     837                 :           0 :        call get_command_argument(ii + iarg, arg, status=istat)
     838         [ #  # ]:           0 :        if (istat == 0) then
     839                 :             :          !write(std_out, *)"arg:", trim(arg)
     840         [ #  # ]:           0 :          if (startswith(arg, "--")) exit
     841                 :           0 :          read(arg,*, iostat=istat, iomsg=iomsg) argval(iarg)
     842         [ #  # ]:           0 :          if (istat == 0) then
     843                 :           0 :            lenr = lenr + 1
     844                 :             :          else
     845   [ #  #  #  # ]:           0 :            ierr = ierr + 1; msg = sjoin(msg, ch10, iomsg)
     846                 :             :          end if
     847                 :             :        else
     848                 :             :          ! If there are less than NUMBER arguments specified at the command line, VALUE will be filled with blanks.
     849         [ #  # ]:           0 :          if (arg == "") exit
     850   [ #  #  #  # ]:           0 :          ierr = ierr + 1; msg = sjoin(msg, ch10, "Error in get_command_argument")
     851                 :             :        end if
     852                 :             :      end do
     853                 :             :    end if
     854                 :             :  end do
     855                 :             : 
     856   [ #  #  #  #  :           0 :  if (ierr /= 0) msg = sjoin("Error while reading argument: ", argname, ch10, msg)
                   #  # ]
     857         [ #  # ]:           0 :  if (found_argname .and. found_excl) then
     858   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = sjoin("Variables", argname, "and", exclude, "are mutually exclusive", ch10, msg)
     859                 :             :  end if
     860                 :             : 
     861         [ #  # ]:           0 :  if (present(want_len)) then
     862         [ #  # ]:           0 :    if (found_argname) then
     863         [ #  # ]:           0 :      if (want_len /= lenr) then
     864                 :           0 :        ierr = ierr + 1
     865   [ #  #  #  # ]:           0 :        msg = sjoin(argname, "requires", itoa(want_len), " tokens while found ", itoa(lenr), ch10, msg)
     866                 :             :      end if
     867                 :             :    else
     868                 :           0 :      ierr = ierr + 1
     869   [ #  #  #  # ]:           0 :      msg = sjoin("Cannot find --", argname, "option in CLI and want_len:", itoa(want_len), ch10, msg)
     870                 :             :    end if
     871                 :             :  end if
     872                 :             : 
     873         [ #  # ]:           0 : end function get_arg_list_int
     874                 :             : !!***
     875                 :             : 
     876                 :             : !----------------------------------------------------------------------
     877                 :             : 
     878                 :             : !!****f* m_argparse/get_arg_list_dp
     879                 :             : !! NAME
     880                 :             : !!  get_arg_list_dp
     881                 :             : !!
     882                 :             : !! FUNCTION
     883                 :             : !!
     884                 :             : !! INPUT
     885                 :             : !!  argname
     886                 :             : !!  [default]
     887                 :             : !!  [default_list]
     888                 :             : !!  [exclude]
     889                 :             : !!  [want_len]
     890                 :             : !!
     891                 :             : !! OUTPUT
     892                 :             : !!  argval
     893                 :             : !!  msg
     894                 :             : !!
     895                 :             : !! SOURCE
     896                 :             : 
     897   [ #  #  #  #  :           0 : integer function get_arg_list_dp(argname, argval, lenr, msg, default, default_list, exclude, want_len) result(ierr)
                   #  # ]
     898                 :             : 
     899                 :             : !Arguments ------------------------------------
     900                 :             : !scalars
     901                 :             :  character(len=*),intent(in) :: argname
     902                 :             :  real(dp),intent(out) :: argval(:)
     903                 :             :  integer,intent(out) :: lenr
     904                 :             :  character(len=*),intent(out) :: msg
     905                 :             :  character(len=*),optional,intent(in) :: exclude
     906                 :             :  real(dp),optional,intent(in) :: default
     907                 :             :  real(dp),optional,intent(in) :: default_list(:)
     908                 :             :  integer,optional,intent(in) :: want_len
     909                 :             : 
     910                 :             : !Local variables-------------------------------
     911                 :             :  integer :: ii, istat, iarg, maxlen
     912                 :             :  logical :: found_argname, found_excl
     913                 :             :  character(len=500) :: arg, iomsg
     914                 :             : 
     915                 :             : ! *************************************************************************
     916                 :             : 
     917         [ #  # ]:           0 :  ierr = 0; msg = ""; lenr = 0
     918                 :           0 :  found_argname = .False.; found_excl = .False.
     919                 :             : 
     920                 :           0 :  maxlen = size(argval);
     921         [ #  # ]:           0 :  if (maxlen == 0) then
     922   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = "zero-sized argval!"; return
     923                 :             :  end if
     924                 :             : 
     925   [ #  #  #  # ]:           0 :  if (present(default)) argval = default
     926   [ #  #  #  # ]:           0 :  if (present(default_list)) argval = default_list
     927                 :             : 
     928         [ #  # ]:           0 :  do ii=1,command_argument_count()
     929                 :           0 :    call get_command_argument(ii, arg)
     930         [ #  # ]:           0 :    if (present(exclude)) then
     931         [ #  # ]:           0 :      if (arg == "--" // trim(exclude)) found_excl = .True.
     932                 :             :    end if
     933         [ #  # ]:           0 :    if (arg == "--" // trim(argname)) then
     934                 :             :      ! Read list of values
     935                 :           0 :      found_argname = .True.
     936         [ #  # ]:           0 :      do iarg=1,maxlen
     937                 :           0 :        call get_command_argument(ii + iarg, arg, status=istat)
     938         [ #  # ]:           0 :        if (istat == 0) then
     939                 :             :          !write(std_out, *)"arg:", trim(arg)
     940         [ #  # ]:           0 :          if (startswith(arg, "--")) exit
     941                 :           0 :          read(arg,*, iostat=istat, iomsg=iomsg) argval(iarg)
     942         [ #  # ]:           0 :          if (istat == 0) then
     943                 :           0 :            lenr = lenr + 1
     944                 :             :          else
     945   [ #  #  #  # ]:           0 :            ierr = ierr + 1; msg = sjoin(msg, ch10, iomsg)
     946                 :             :          end if
     947                 :             :        else
     948                 :             :          ! If there are less than NUMBER arguments specified at the command line, VALUE will be filled with blanks.
     949         [ #  # ]:           0 :          if (arg == "") exit
     950   [ #  #  #  # ]:           0 :          ierr = ierr + 1; msg = sjoin(msg, ch10, "Error in get_command_argument")
     951                 :             :        end if
     952                 :             :      end do
     953                 :             :    end if
     954                 :             :  end do
     955                 :             : 
     956   [ #  #  #  #  :           0 :  if (ierr /= 0) msg = sjoin("Error while reading argument: ", argname, ch10, msg)
                   #  # ]
     957         [ #  # ]:           0 :  if (found_argname .and. found_excl) then
     958   [ #  #  #  # ]:           0 :    ierr = ierr + 1; msg = sjoin("Variables", argname, "and", exclude, "are mutually exclusive", ch10, msg)
     959                 :             :  end if
     960                 :             : 
     961         [ #  # ]:           0 :  if (present(want_len)) then
     962         [ #  # ]:           0 :    if (found_argname) then
     963         [ #  # ]:           0 :      if (want_len /= lenr) then
     964                 :           0 :        ierr = ierr + 1
     965   [ #  #  #  # ]:           0 :        msg = sjoin(argname, "requires", itoa(want_len), " tokens while found ", itoa(lenr), ch10, msg)
     966                 :             :      end if
     967                 :             :    else
     968                 :           0 :      ierr = ierr + 1
     969   [ #  #  #  # ]:           0 :      msg = sjoin("Cannot find --", argname, " option in CLI and want_len:", itoa(want_len), ch10, msg)
     970                 :             :    end if
     971                 :             :  end if
     972                 :             : 
     973         [ #  # ]:           0 : end function get_arg_list_dp
     974                 :             : !!***
     975                 :             : 
     976                 :             : !----------------------------------------------------------------------
     977                 :             : 
     978                 :             : !!****f* ABINIT/parse_kargs
     979                 :             : !! NAME
     980                 :             : !! parse_kargs
     981                 :             : !!
     982                 :             : !! FUNCTION
     983                 :             : !!  Parse command line arguments, return options related to k-point sampling
     984                 :             : !!
     985                 :             : !! INPUTS
     986                 :             : !!
     987                 :             : !! OUTPUT
     988                 :             : !!
     989                 :             : !! SOURCE
     990                 :             : 
     991                 :           0 : subroutine parse_kargs(kptopt, kptrlatt, nshiftk, shiftk, chksymbreak)
     992                 :             : 
     993                 :             : !Arguments ------------------------------------
     994                 :             :  integer,intent(out) :: kptopt, nshiftk, chksymbreak
     995                 :             :  integer,intent(out) :: kptrlatt(3,3)
     996                 :             :  real(dp),allocatable,intent(out) :: shiftk(:,:)
     997                 :             : 
     998                 :             : !Local variables-------------------------------
     999                 :             :  integer :: ii, lenr, ierr
    1000                 :             :  character(len=500) :: msg
    1001                 :             :  integer :: ivec9(9), ngkpt(3)
    1002                 :             :  real(dp) :: my_shiftk(3 * MAX_NSHIFTK)
    1003                 :             : 
    1004                 :             : ! *************************************************************************
    1005                 :             : 
    1006         [ #  # ]:           0 :  ABI_CHECK(get_arg("kptopt", kptopt, msg, default=1) == 0, msg)
    1007         [ #  # ]:           0 :  ABI_CHECK(get_arg("chksymbreak", chksymbreak, msg, default=1) == 0, msg)
    1008                 :             : 
    1009                 :           0 :  ierr = get_arg_list("ngkpt", ngkpt, lenr, msg, exclude="kptrlatt", want_len=3)
    1010         [ #  # ]:           0 :  if (ierr == 0) then
    1011                 :             :  !if (lenr == 3) then
    1012                 :           0 :    kptrlatt = 0
    1013         [ #  # ]:           0 :    do ii=1,3
    1014                 :           0 :      kptrlatt(ii, ii) = ngkpt(ii)
    1015                 :             :    end do
    1016                 :             :  else
    1017         [ #  # ]:           0 :    ABI_CHECK(get_arg_list("kptrlatt", ivec9, lenr, msg, exclude="ngkpt", want_len=9) == 0, msg)
    1018         [ #  # ]:           0 :    ABI_CHECK(lenr == 9, "Expecting 9 values for kptrlatt")
    1019   [ #  #  #  # ]:           0 :    kptrlatt = transpose(reshape(ivec9, [3, 3]))
    1020                 :             :  end if
    1021                 :             : 
    1022                 :             :  ! Init default
    1023         [ #  # ]:           0 :  ABI_CHECK(get_arg_list("shiftk", my_shiftk, lenr, msg) == 0, msg)
    1024         [ #  # ]:           0 :  if (lenr /= 0) then
    1025         [ #  # ]:           0 :    ABI_CHECK(mod(lenr, 3) == 0, "Expecting 3 * nshift array")
    1026                 :           0 :    nshiftk = lenr / 3
    1027   [ #  #  #  #  :           0 :    ABI_MALLOC(shiftk, (3, nshiftk))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1028   [ #  #  #  #  :           0 :    shiftk = reshape(my_shiftk(1:lenr), [3, nshiftk])
             #  #  #  # ]
    1029                 :             :  else
    1030                 :           0 :    nshiftk = 1
    1031   [ #  #  #  #  :           0 :    ABI_CALLOC(shiftk, (3, nshiftk))
             #  #  #  # ]
    1032                 :             :    !shiftk(:, 1) = [half, half, half]
    1033                 :             :  end if
    1034                 :             :  !write(std_out, *)"kptopt = ", kptopt, ", chksymbreak = ", chksymbreak, ", nshiftk = ", nshiftk, ", kptrlatt = ", kptrlatt
    1035                 :             : 
    1036                 :           0 : end subroutine parse_kargs
    1037                 :             : !!***
    1038                 :             : 
    1039                 :           0 : end module m_argparse
    1040                 :             : !!***
        

Generated by: LCOV version 2.3-1