Changeset 4191


Ignore:
Timestamp:
Apr 17, 2026, 2:21:31 PM (2 weeks ago)
Author:
jbclement
Message:

COMMON:
Standardization and improvements of version control and command line options for the programs.
JBC

Location:
trunk
Files:
11 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.COMMON/libf/dyn3d/gcm.F90

    r3836 r4191  
    3030  USE temps_mod, ONLY: calend,start_time,annee_ref,day_ref, &
    3131                itau_dyn,itau_phy,day_ini,jD_ref,jH_ref,day_end
    32   use parse_args_mod, only: parse_args
     32  use program_options, only: parse_args
    3333
    3434
  • trunk/LMDZ.COMMON/libf/dyn3dpar/gcm.F

    r3836 r4191  
    2727     &                       ecritstart
    2828      use cpdet_mod, only: ini_cpdet
    29       use parse_args_mod, only: parse_args
     29      use program_options, only: parse_args
    3030
    3131
  • trunk/LMDZ.COMMON/libf/evolution/pem.F90

    r4189 r4191  
    2222! DEPENDENCIES
    2323! ------------
    24 ! Common modules
    25 use job_mod,        only: timelimit, antetime, timewall
    26 use parse_args_mod, only: parse_args
     24! LMDZ.COMMON modules
     25use job,             only: timelimit, antetime, timewall
     26use program_options, only: parse_args
    2727! PEM modules
    2828use allocation,         only: ini_allocation, end_allocation
    2929use atmosphere,         only: ps_PCM, evolve_pressure, CO2cond_ps_PCM
    3030use backup,             only: save_clim_state, backup_rate
    31 use climate_init,    only: read_start, read_startfi, read_startevo
     31use climate_init,       only: read_start, read_startfi, read_startevo
    3232use config,             only: read_rundef, read_display_config
    3333use display,            only: print_ini, print_end, print_msg, is_lvl_enabled, LVL_NFO, LVL_WRN, LVL_DBG
     
    105105call parse_args()
    106106
     107! Read display configuration
     108call read_display_config()
     109
    107110! Initialization
    108111! ~~~~~~~~~~~~~~
    109112! Header
    110 call read_display_config()
    111113call print_ini()
    112114
  • trunk/LMDZ.COMMON/libf/misc/job.F90

    r4190 r4191  
    1 MODULE job_mod
     1MODULE job
    22
    33!-----------------------------------------------------------------------
    44! NAME
    5 !     job_mod
     5!     job
    66!
    77! DESCRIPTION
     
    99!
    1010! AUTHORS & DATE
    11 !     JB Clement, 10/06/2024
     11!     JB Clement, 07/07/2025
    1212!
    1313! NOTES
     
    3838!
    3939! AUTHORS & DATE
    40 !     JB Clement, 10/06/2024
     40!     JB Clement, 07/07/2025
    4141!
    4242! NOTES
     
    6464    jobid = trim(adjustl(tmp))
    6565    return
    66 endif
     66end if
    6767
    68 ! Try PBS/TORQUE 
     68! Try PBS/TORQUE
    6969call get_environment_variable("PBS_JOBID",tmp,status = sts)
    7070if (sts == 0 .and. len_trim(tmp) > 0) then
     
    7272    jobid = trim(adjustl(tmp(1:index(tmp,'.') - 1)))
    7373    return
    74 endif
     74end if
    7575
    7676error stop 'Error: neither SLURM_JOB_ID nor PBS_JOBID found in environment!'
     
    9090!
    9191! AUTHORS & DATE
    92 !     JB Clement, 10/06/2024
     92!     JB Clement, 07/07/2025
    9393!
    9494! NOTES
     
    119119        num_str = .false.
    120120        exit
    121     endif
    122 enddo
     121    end if
     122end do
    123123if (.not. num_str) error stop "Error: job ID must be numeric!"
    124124
     
    132132    else if (cstat < 0) then
    133133        error stop 'Error: command execution not supported (neither SLURM nor PBS/TORQUE is installed)!'
    134     endif
    135 endif
     134    end if
     135end if
    136136
    137137! Read the output
     
    148148else if (cstat < 0) then
    149149    error stop 'Error: command execution not supported!'
    150 endif
     150end if
    151151
    152152! Parse D-HH:MM:SS, HH:MM:SS or MM:SS
     
    160160    read(chtimelimit,'(i2,a1,i2)') minutes, sep, seconds
    161161    timelimit = real(minutes)*60. + real(seconds)
    162 endif
     162end if
    163163
    164164timewall = .true.
     
    167167!=======================================================================
    168168
    169 END MODULE job_mod
     169END MODULE job
  • trunk/LMDZ.COMMON/libf/misc/program_options.F90

    r4190 r4191  
    1 MODULE parse_args_mod
    2 
    3 !***********************************************************************
    4 ! DESCRIPTION:
    5 !    Provides a subroutine to parse command-line options.
    6 !    Recognizes:
    7 !       --help
    8 !       --version [file]
    9 !       --jobid <id>
    10 !       --add-sso
    11 !***********************************************************************
    12 
     1MODULE program_options
     2
     3!-----------------------------------------------------------------------
     4! NAME
     5!     program_options
     6!
     7! DESCRIPTION
     8!     Tools to parse command-line options.
     9!
     10! AUTHORS & DATE
     11!     JB Clement, 07/07/2025
     12!
     13! NOTES
     14!
     15!-----------------------------------------------------------------------
     16
     17! DEPENDENCIES
     18! ------------
    1319#ifndef MESOSCALE
    14 use pgrm_version_mod, only: print_pgrm_version
     20use version_control, only: print_pgrm_version
    1521#endif
    16 use job_mod,           only: get_job_id, get_job_timelimit
    17 
    18 implicit none
    19 
     22use job,             only: get_job_id, get_job_timelimit
     23
     24! DECLARATION
     25! -----------
     26implicit none
     27
     28! PARAMETERS
     29! ----------
    2030logical :: add_sso_fields = .false. ! Default: do not include SSO fields
    2131
    22 !=======================================================================
     32
    2333contains
    24 !=======================================================================
    25 
     34!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     35
     36!=======================================================================
    2637SUBROUTINE parse_args()
    2738
    28 implicit none
    29 
    30 !---- Arguments
    31 
    32 !---- Variables
     39!-----------------------------------------------------------------------
     40! NAME
     41!     parse_args
     42!
     43! DESCRIPTION
     44!     Parse command-line options.
     45!
     46! AUTHORS & DATE
     47!     JB Clement, 07/07/2025
     48!
     49! NOTES
     50!     Recognizes:
     51!         --help
     52!         --version [file]
     53!         --jobid <id>
     54!         --add-sso
     55!-----------------------------------------------------------------------
     56
     57! DECLARATION
     58! -----------
     59implicit none
     60
     61! LOCAL VARIABLES
     62! ---------------
    3363integer        :: narg, i, eq_pos
    3464character(256) :: arg, key, vlu, jobid
    3565
    36 !---- Code
     66! CODE
     67! ----
    3768narg = command_argument_count() ! Get the number of command-line arguments
    3869if (narg == 0) return ! No option: normal/default case, nothing to do
     
    5485                vlu = strip(arg)
    5586                i = i + 1 ! To skip the value argument next time
    56             endif
    57         endif
    58     endif
     87            end if
     88        end if
     89    end if
    5990
    6091    select case (to_lower(key))
     
    69100            else
    70101                call print_pgrm_version()
    71             endif
     102            end if
    72103            call exit(0)
    73104#endif
     
    87118
    88119    i = i + 1
    89 enddo
     120end do
    90121
    91122END SUBROUTINE parse_args
    92123!=======================================================================
    93124
     125!=======================================================================
    94126SUBROUTINE print_usage()
    95     write(*,*)
    96     write(*,*) 'Usage: program [options]'
    97     write(*,*) '  --help              Show this help message and exit'
    98     write(*,*) '  --version [file]    Print program version and exit (optional output file)'
    99     write(*,*) '  --add-sso           Add SSO fields to "start_archive.nc" (only available for Mars start2archive)'
    100     write(*,*) '  --auto-exit         Enable automatic termination before reaching the job time limit (only available for the PEM)'
    101     write(*,*)
     127!-----------------------------------------------------------------------
     128! NAME
     129!     print_usage
     130!
     131! DESCRIPTION
     132!     Print the usage message.
     133!
     134! AUTHORS & DATE
     135!     JB Clement, 07/07/2025
     136!
     137! NOTES
     138!
     139!-----------------------------------------------------------------------
     140
     141! DECLARATION
     142! -----------
     143implicit none
     144
     145! CODE
     146! ----
     147write(*,*)
     148write(*,*) 'Usage: program [options]'
     149write(*,*) '  --help              Show this help message and exit'
     150write(*,*) '  --version [file]    Print program version and exit (optional output file)'
     151write(*,*) '  --add-sso           Add SSO fields to "start_archive.nc" (only available for Mars start2archive)'
     152write(*,*) '  --auto-exit         Enable automatic termination before reaching the job time limit (only available for the PEM)'
     153write(*,*)
     154
    102155END SUBROUTINE print_usage
    103156!=======================================================================
    104157
     158!=======================================================================
    105159PURE FUNCTION strip(s) RESULT(t)
    106 
    107 implicit none
    108 
    109 !---- Arguments
     160!-----------------------------------------------------------------------
     161! NAME
     162!     strip
     163!
     164! DESCRIPTION
     165!     Remove leading and trailing whitespace from a string.
     166!
     167! AUTHORS & DATE
     168!     JB Clement, 07/07/2025
     169!
     170! NOTES
     171!
     172!-----------------------------------------------------------------------
     173
     174! DECLARATION
     175! -----------
     176implicit none
     177
     178! ARGUMENTS
     179! ---------
    110180character(*), intent(in) :: s
     181
     182! LOCAL VARIABLES
     183! ---------------
    111184character(len(s)) :: t
    112185
    113 !---- Variables
    114 
    115 !---- Code
     186! CODE
     187! ----
    116188t = trim(adjustl(s))
    117189
    118 END FUNCTION
    119 !=======================================================================
    120 
     190END FUNCTION strip
     191!=======================================================================
     192
     193!=======================================================================
    121194PURE FUNCTION to_lower(s) RESULT(low)
    122 
    123 implicit none
    124 
    125 !---- Arguments
     195!-----------------------------------------------------------------------
     196! NAME
     197!     to_lower
     198!
     199! DESCRIPTION
     200!     Convert a string to lowercase.
     201!
     202! AUTHORS & DATE
     203!     JB Clement, 07/07/2025
     204!
     205! NOTES
     206!
     207!-----------------------------------------------------------------------
     208
     209! DECLARATION
     210! -----------
     211implicit none
     212
     213! ARGUMENTS
     214! ---------
    126215character(*), intent(in) :: s
     216
     217! LOCAL VARIABLES
     218! ---------------
    127219character(len(s)) :: low
    128 
    129 !---- Variables
    130 integer :: i
    131 
    132 !---- Code
     220integer           :: i
     221
     222! CODE
     223! ----
    133224low = s
    134225do i = 1,len(s)
    135226    if (iachar(s(i:i)) >= iachar('A') .and. iachar(s(i:i)) <= iachar('Z')) low(i:i) = achar(iachar(s(i:i)) + 32)
    136 enddo
     227end do
    137228
    138229END FUNCTION to_lower
    139 
    140 
    141 END MODULE parse_args_mod
     230!=======================================================================
     231
     232END MODULE program_options
  • trunk/LMDZ.COMMON/makelmdz_fcm

    r3985 r4191  
    598598
    599599# Path and name of the generated file
    600 version_F90file="$LIBFGCM/misc/pgrm_version.F90"
     600version_F90file="$LIBFGCM/misc/version_control.F90"
    601601
    602602# Path and name of the file containing the compilation and version details
    603 default_out_file="pgrm_version_details.txt"
     603default_filename="pgrm_version_control.txt"
    604604
    605605# Get the current date
     
    649649# Generate the Fortran subroutine
    650650cat << EOF > "$version_F90file"
    651 MODULE pgrm_version_mod
    652 
    653 !***********************************************************************
    654 ! File generated automatically at compilation
     651MODULE version_control
     652!-----------------------------------------------------------------------
     653! NAME
     654!     version_control
    655655!
    656 ! DESCRIPTION:
    657 !    The subroutine 'print_pgrm_version' prints compilation details, the version
    658 !    control information (SVN or Git), the status and the diff result if applicable.
     656! DESCRIPTION
     657!     Manage compilation details and version control information for the
     658!     program.
    659659!
    660 ! PARAMETERS:
    661 !    None.
     660! AUTHORS & DATE
     661!     JB Clement, 07/07/2025
    662662!
    663 ! USAGE:
    664 !    Use the command-line option "--version [file]" when running your program:
    665 !       ./myprogram --version [file]
    666 !    This will write compilation and version details into the specified [file].
    667 !    If [file] is omitted, the default name "pgrm_version_details.txt" will be used.
    668 !    This feature helps track code builds and their exact compilation context
    669 !    directly from the executable.
    670 !***********************************************************************
    671 
     663! NOTES
     664!    File generated automatically at compilation to include compilation
     665!    details and version control information in the executable.
     666!-----------------------------------------------------------------------
     667
     668! DECLARATIONS
     669! ------------
    672670implicit none
    673671
    674 character(*), parameter :: default_out_file = "${default_out_file}"
     672! PARAMETERS
     673! ----------
     674character(*),   parameter, private :: default_filename = "${default_filename}" ! Default name for the output file
     675character(128), protected, private :: curr_dir = ' ' ! Current directory
     676character(32),  protected, private :: username = ' ' ! User name
     677character(32),  protected, private :: hostname = ' ' ! Machine/station name
     678character(128), protected, private :: cmd_pgrm = ' ' ! Command used to run the programm
     679character(8),   protected, private :: date = ' '     ! Current date (YYYYMMDD)
     680character(10),  protected, private :: time = ' '     ! Current time (hhmmss.sss)
     681character(5),   protected, private :: zone = ' '     ! UTC offset (+/-hhmm)
     682
     683contains
     684!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    675685
    676686!=======================================================================
    677 contains
    678 !=======================================================================
    679 
    680 SUBROUTINE print_pgrm_version(user_out_file)
    681 
    682 !---- Arguments
    683 character(*), optional, intent(in) :: user_out_file
    684 
    685 !---- Variables
    686 integer, parameter        :: io_unit = 10
    687 character(:), allocatable :: out_file
    688 
    689 !---- Code
    690 if (present(user_out_file)) then
    691     out_file = trim(adjustl(user_out_file))
     687SUBROUTINE print_pgrm_version(user_filename)
     688!-----------------------------------------------------------------------
     689! NAME
     690!     print_pgrm_version
     691!
     692! DESCRIPTION
     693!     Prints compilation details and the results of the version control
     694!     information (SVN or Git), with commannds "info", "status" and
     695!     "diff" if applicable.
     696!
     697!     Use the command-line option "--version [file]" when running your
     698!     program:
     699!         ./myprogram --version [file]
     700!     This will write compilation details and version control information
     701!     into the specified [file]. If [file] is omitted, the default name
     702!     "pgrm_version_control.txt" will be used.
     703!
     704! AUTHORS & DATE
     705!     JB Clement, 07/07/2025
     706!
     707! NOTES
     708!     This feature helps track code builds and their exact compilation
     709!     context directly from the executable.
     710!-----------------------------------------------------------------------
     711
     712! DECLARATIONS
     713! ------------
     714implicit none
     715
     716! ARGUMENTS
     717! ---------
     718character(*), optional, intent(in) :: user_filename
     719
     720! LOCAL VARIABLES
     721! ---------------
     722integer                   :: funit, ierr
     723character(:), allocatable :: filename
     724integer, dimension(8)     :: values
     725
     726! CODE
     727! ----
     728! Some user info
     729call date_and_time(date,time,zone,values)
     730call getcwd(curr_dir)
     731call getlog(username)
     732call hostnm(hostname)
     733call get_command(cmd_pgrm)
     734
     735! Open the file
     736filename = trim(adjustl(default_filename))
     737if (present(user_filename)) filename = trim(adjustl(user_filename))
     738open(newunit = funit,file = filename,status = "replace",action = "write",iostat = ierr)
     739if (ierr /= 0) error stop 'error opening file "'//filename//'"!'
     740
     741! Write compilation details
     742write(*,*)
     743write(*,'(a)') 'Generating program control file: "'//filename//'"'
     744write(funit,'(a)') '########################################################################'
     745write(funit,'(a)') '########################### PROGRAM CONTROL ############################'
     746write(funit,'(a)') '########################################################################'
     747write(funit,*)
     748write(funit,'(a)') '> User     : '//trim(adjustl(username))
     749write(funit,'(a)') '> Machine  : '//trim(adjustl(hostname))
     750write(funit,'(a)') '> Directory: '//trim(adjustl(curr_dir))
     751write(funit,'(a)') '> Command  : '//trim(adjustl(cmd_pgrm))
     752write(funit,'(a,a4,a,a2,a,a2)') '> Date     : ',date(1:4),'-',date(5:6),'-',date(7:8)
     753write(funit,'(a,a2,a,a2,a,a2,a,a3)') '> Time     : ',time(1:2),':',time(3:4),':',time(5:6),'.',time(8:10)
     754if (zone(1:1) == '+' .or. zone(1:1) == '-') then
     755    write(funit,'(a,a1,a2,a,a2)') '> Timezone : UTC',zone(1:1),zone(2:3),':',zone(4:5)
    692756else
    693     out_file = trim(adjustl(default_out_file))
    694 endif
    695 
    696 open(io_unit,file = out_file,status = 'replace',action = 'write')
    697 
    698 write(*,*)
    699 write(*,'(a)') '-> Writing compilation details to the file "'//out_file//'".'
    700 write(io_unit,'(a)') '========================= COMPILATION DETAILS =========================='
    701 write(io_unit,'(a)') '-> Date   : ${current_date}'
    702 write(io_unit,'(a)') '-> Command: ${compilation_command}'
    703 write(io_unit,*)
     757    write(funit,'(a,i0,a)') '> Timezone : unknown (offset=',values(4),' min)'
     758end if
     759write(funit,*)
     760write(*,'(a)') '    > Writing compilation details...'
     761write(funit,'(a)') '######################### COMPILATION DETAILS ##########################'
     762write(funit,'(a)') '> Date   : ${current_date}'
     763write(funit,'(a)') '> Command: ${compilation_command}'
     764write(funit,*)
     765
     766! Write version control information
    704767EOF
    705768
    706769if [ -n "$vcs_info" ]; then
    707     echo "write(*,'(a)') '-> Writing information result to the file \"'//out_file//'\".'" >> "$version_F90file"
    708     echo "write(io_unit,'(a)') '===================== VERSION CONTROL INFORMATION ======================'" >> "$version_F90file"
     770    echo "write(*,'(a)') '    > Writing info result...'" >> "$version_F90file"
     771  echo "write(funit,'(a)') '##################### VERSION CONTROL INFORMATION ######################'" >> "$version_F90file"
    709772    while IFS= read -r line; do
    710         echo "write(io_unit,'(a)') '${line}'" >> "$version_F90file"
     773        echo "write(funit,'(a)') '${line}'" >> "$version_F90file"
    711774    done <<< "$(echo -e "$vcs_info")"
    712775else
    713     echo "write(io_unit,'(a)') '====================== NO VERSION CONTROL SYSTEM ======================='" >> "$version_F90file"
     776  echo "write(funit,'(a)') '###################### NO VERSION CONTROL SYSTEM #######################'" >> "$version_F90file"
    714777fi
    715778
    716779if [ -n "$vcs_stat" ]; then
    717     echo "write(*,'(a)') '-> Writing status result to the file \"'//out_file//'\".'" >> "$version_F90file"
    718     echo "write(io_unit,*)" >> "$version_F90file"
    719     echo "write(io_unit,'(a)') '======================== VERSION CONTROL STATUS ========================'" >> "$version_F90file"
     780    echo "write(*,'(a)') '    > Writing status result...'" >> "$version_F90file"
     781    echo "write(funit,*)" >> "$version_F90file"
     782  echo "write(funit,'(a)') '######################## VERSION CONTROL STATUS ########################'" >> "$version_F90file"
    720783    while IFS= read -r line; do
    721         echo "write(io_unit,'(a)') '${line}'" >> "$version_F90file"
     784        echo "write(funit,'(a)') '${line}'" >> "$version_F90file"
    722785    done <<< "$(echo -e "$vcs_stat")"
    723786fi
    724787
    725788if [ -n "$vcs_diff" ]; then
    726     echo "write(*,'(a)') '-> Writing diff result to the file \"'//out_file//'\".'" >> "$version_F90file"
    727     echo "write(io_unit,*)" >> "$version_F90file"
    728     echo "write(io_unit,'(a)') '========================= VERSION CONTROL DIFF ========================='" >> "$version_F90file"
     789    echo "write(*,'(a)') '    > Writing diff result...'" >> "$version_F90file"
     790    echo "write(funit,*)" >> "$version_F90file"
     791  echo "write(funit,'(a)') '######################### VERSION CONTROL DIFF #########################'" >> "$version_F90file"
    729792    while IFS= read -r line; do
    730         echo "write(io_unit,'(a)') '${line}'" >> "$version_F90file"
     793        echo "write(funit,'(a)') '${line}'" >> "$version_F90file"
    731794    done <<< "$(echo -e "$vcs_diff")"
    732795fi
    733796
    734797cat << EOF >> "$version_F90file"
    735 write(io_unit,'(a)') '========================================================================'
     798write(funit,'(a)') '########################################################################'
     799
     800! Close the file
     801close(funit)
     802write(*,'(a)') 'Done!'
    736803write(*,*)
    737804
    738 close(io_unit)
    739 
    740805END SUBROUTINE print_pgrm_version
    741 
    742 END MODULE pgrm_version_mod
     806!=======================================================================
     807
     808END MODULE version_control
    743809EOF
    744810
  • trunk/LMDZ.GENERIC/libf/dynphy_lonlat/phygeneric/newstart.F

    r3908 r4191  
    5252     &                         latitude,  ! latitudes (rad)                       
    5353     &                         cell_area ! physics grid area (m2)
    54       use parse_args_mod, only: parse_args
     54      use program_options, only: parse_args
    5555                       
    5656      implicit none
  • trunk/LMDZ.GENERIC/libf/dynphy_lonlat/phygeneric/start2archive.F

    r3946 r4191  
    3939     &                          east_gwstress, west_gwstress
    4040      use exner_hyb_m, only: exner_hyb
    41       use parse_args_mod, only: parse_args
     41      use program_options, only: parse_args
    4242
    4343      implicit none
  • trunk/LMDZ.GENERIC/libf/phygeneric/dyn1d/kcm1d.F90

    r4146 r4191  
    2222  use dimphy, only : init_dimphy
    2323  use gases_h, only: ngasmx
    24   use parse_args_mod, only: parse_args
     24  use program_options, only: parse_args
    2525
    2626  implicit none
  • trunk/LMDZ.GENERIC/libf/phygeneric/dyn1d/rcm1d.F

    r4146 r4191  
    4343     &                  nf90_strerror,NF90_INQ_VARID, NF90_GET_VAR,
    4444     &                  NF90_CLOSE
    45       use parse_args_mod, only: parse_args
     45      use program_options, only: parse_args
    4646      !use inichim_1D_mod, only: inichim_1D
    4747      !use initracer_1D_mod, only: initracer_1D
  • trunk/LMDZ.MARS/libf/dynphy_lonlat/phymars/newstart.F

    r4166 r4191  
    6363     &             coef_ssdif, ini_paleoclimate, end_paleoclimate
    6464      use subslope_mola_mod, ONLY: subslope_mola
    65       use parse_args_mod, only: parse_args
     65      use program_options, only: parse_args
    6666     
    6767      implicit none
  • trunk/LMDZ.MARS/libf/dynphy_lonlat/phymars/start2archive.F

    r3836 r4191  
    4141      USE surfdat_h, ONLY: phisfi, albedodat, z0, z0_default,
    4242     &    zmea, zstd, zsig, zgam, zthe, hmons, summit, base
    43       use parse_args_mod, only: parse_args, add_sso_fields
     43      use program_options, only: parse_args, add_sso_fields
    4444
    4545      implicit none
  • trunk/LMDZ.MARS/libf/phymars/dyn1d/testphys1d.F90

    r4067 r4191  
    1818use init_testphys1d_mod, only: init_testphys1d
    1919use writerestart1D_mod,  only: writerestart1D
    20 use parse_args_mod,      only: parse_args
     20use program_options,     only: parse_args
    2121use callkeys_mod,        only: water
    2222! Mostly for XIOS outputs
Note: See TracChangeset for help on using the changeset viewer.