source: trunk/libIGCM/libIGCM_config/libIGCM_config.ksh @ 1426

Last change on this file since 1426 was 1426, checked in by aclsce, 6 years ago
  • Added the use of NOD parameter in config.card. This functionality is only available on Curie and for XIOS component (in order to assign XIOS servers on different nodes).

Example :
IOS= (xios_server.exe, xios.x, 4MPI, 2NOD)
means 4 XIOS servers use 2 computing nodes (i.e 2 XIOS servers per node).

  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

    The fact that you are presently reading this means that you have had
    knowledge of the CeCILL license and that you accept its terms.
  • Property svn:keywords set to Revision Author Date
File size: 54.2 KB
Line 
1#!/bin/ksh
2
3#**************************************************************
4# Author: Sebastien Denvil, Martial Mancip
5# Contact: Sebastien.Denvil__at__ipsl.jussieu.fr Martial.Mancip__at__ipsl.jussieu.fr
6# $Revision::                                          $ Revision of last commit
7# $Author::                                            $ Author of last commit
8# $Date::                                              $ Date of last commit
9# IPSL (2006)
10#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
11#
12#**************************************************************
13
14#===================================
15function IGCM_config_CommonConfiguration
16{
17  IGCM_debug_PushStack "IGCM_config_CommonConfiguration" $@
18
19  # Debug Print :
20  [ ${Verbosity} -gt 0 ] && echo
21  IGCM_debug_Print 1 "IGCM_config_CommonConfiguration" $@
22
23  # config.card path
24  configCardPath=$1
25
26  #==================================
27  typeset option auxprint
28
29  #==================================
30  # Read UserChoices section:
31  [ ${Verbosity} -gt 0 ] && echo
32  IGCM_debug_Print 1 "DefineArrayFromOption  : config_UserChoices"
33
34  IGCM_card_DefineArrayFromSection ${configCardPath} UserChoices
35  for option in ${config_UserChoices[*]} ; do
36    IGCM_card_DefineVariableFromOption ${configCardPath} UserChoices ${option}
37    eval auxprint=\${config_UserChoices_${option}}
38    IGCM_debug_Print 3 "${option} : ${auxprint}"
39  done
40
41  #==================================
42  # Read Ensemble section:
43  [ ${Verbosity} -gt 0 ] && echo
44  IGCM_debug_Print 1 "DefineArrayFromOption  : config_Ensemble"
45
46  IGCM_card_DefineArrayFromSection ${configCardPath} Ensemble
47  for option in ${config_Ensemble[*]} ; do
48    IGCM_card_DefineVariableFromOption ${configCardPath} Ensemble ${option}
49    eval auxprint=\${config_Ensemble_${option}}
50    IGCM_debug_Print 3 "${option} : ${auxprint}"
51  done
52
53  #==================================
54  # Read Post section:
55  [ ${Verbosity} -gt 0 ] && echo
56  IGCM_debug_Print 1 "DefineArrayFromOption : config_Post"
57
58  IGCM_card_DefineArrayFromSection ${configCardPath} Post
59  for option in ${config_Post[*]} ; do
60    IGCM_card_DefineVariableFromOption ${configCardPath} Post ${option}
61    eval auxprint=\${config_Post_${option}}
62    IGCM_debug_Print 3 "${option} : ${auxprint}"
63  done
64  [ ${Verbosity} -gt 0 ] && echo
65
66  #==================================
67  # Define default value to keep compatibility with previous card: means before changes due to TGCC
68  # Apply some overrules to ensure proper usage of computing centres resources
69  #
70  if [ X${PackDefault} = Xtrue ] ; then
71    if [ X${config_UserChoices_SpaceName} = XTEST ]; then
72      # TEST simulations will not be packed and will stay on SCRATCHDIR filesystem
73      IGCM_debug_Print 1 "SpaceName=TEST. OVERRULE PackFrequency to NONE"
74      config_Post_PackFrequency=NONE
75    else
76      # Default to RebuildFrequency if nothing has been set up related to PackFrequency
77      [ X${config_Post_PackFrequency} = X ] && config_Post_PackFrequency=${config_Post_RebuildFrequency}
78    fi
79  else
80    # If we DO NOT apply pack in this computing center
81    config_Post_PackFrequency=NONE
82  fi
83
84  #====================================================
85  # Define ARCHIVE : Dedicated to large files
86  # Define STORAGE : Dedicated to small/medium files
87  # Define R_OUT   : Output tree located on ARCHIVE
88  # Define R_BUF   : Output tree located on STORAGE (files waiting treatment, or file lcoation when SpaceName=!PROD)
89  # Define R_FIG   : Output tree located on STORAGE hosting figures (monitoring and atlas, and/or small files)
90  # Define R_TMP   : A temporary space used by IGCM_debug_send_AMQP_msg__MAILTUNNEL. Must be persistent in between jobs
91  IGCM_sys_defineArchives
92
93  #====================================================
94  # R_SAVE : Job output directory
95  # R_BUFR : Job output buffered directory
96
97  if ( [ ! X${config_UserChoices_SpaceName} = X ] && [ ! X${config_UserChoices_ExperimentName} = X ] ) ; then
98    FreeName=$( echo ${config_UserChoices_JobName} | sed 's/.*_//' )
99    if ( [ ! X${config_Ensemble_EnsembleName} = X ] && [ ! X${config_Ensemble_EnsembleDate} = X ] ) ; then
100      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
101      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
102      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
103      R_DODS=${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
104    else
105      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
106      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
107      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
108      R_DODS=${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
109    fi
110  else
111    if ( [ ! X${config_Ensemble_EnsembleName} = X ] && [ ! X${config_Ensemble_EnsembleDate} = X ] ) ; then
112      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
113      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
114      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
115      R_DODS=${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
116    else
117      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_UserChoices_JobName}
118      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_UserChoices_JobName}
119      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_UserChoices_JobName}
120      R_DODS=${config_UserChoices_TagName}/${config_UserChoices_JobName}
121    fi
122  fi
123
124  #====================================================
125  # Define R_OUT_KSH : Storage place for job output
126  # Define R_OUT_EXE : Storage place for binary used during simulation
127  R_OUT_KSH=${R_SAVE}/Out
128  R_OUT_EXE=${R_SAVE}/Exe
129
130  #====================================================
131  # Define R_BUF_KSH : Buffer place for job output
132  # Define R_BUF_EXE : Buffer place for binary used during simulation
133  R_BUF_KSH=${R_BUFR}/Out
134  R_BUF_EXE=${R_BUFR}/Exe
135
136  #====================================================
137  # Define REBUILD_DIR : where we store files needing rebuild process
138  REBUILD_DIR=${R_BUFR}/REBUILD
139  if [ ! X${TaskType} = Xchecking ] ; then
140    IGCM_sys_MkdirWork ${REBUILD_DIR}
141  fi
142
143  #====================================================
144  # DodsCopy : apply default value if not defined
145  if ( [ X${config_Post_DodsCopy} = X${NULL_STR} ] || [ X${config_Post_DodsCopy} = X ] ) ; then
146    config_Post_DodsCopy=TRUE
147  fi
148
149  #====================================================
150  # AtlasIPSL : apply default value if not defined
151  if ( [ X${config_Post_AtlasIPSL} = X${NULL_STR} ] || [ X${config_Post_AtlasIPSL} = X ] ) ; then
152    config_Post_AtlasIPSL=TRUE
153  fi
154
155  #====================================================
156  # ParserXIOS : apply default value if not defined
157  if ( [ X${config_Post_ParserXIOS} = X${NULL_STR} ] || [ X${config_Post_ParserXIOS} = X ] ) ; then
158    config_Post_ParserXIOS=FALSE
159  fi
160
161  #====================================================
162  # MetricsPCMDI : apply default value if not defined
163  if ( [ X${config_Post_MetricsPCMDI} = X${NULL_STR} ] || [ X${config_Post_MetricsPCMDI} = X ] ) ; then
164    config_Post_MetricsPCMDI=FALSE
165  fi
166
167  #====================================================
168  # IgnoreNonMonotonic : apply default value if not defined
169  if ( [ X${config_Post_IgnoreNonMonotonic} = X${NULL_STR} ] || [ X${config_Post_IgnoreNonMonotonic} = X ] ) ; then
170    config_Post_IgnoreNonMonotonic=FALSE
171  fi
172
173  #====================================================
174  # LightRestartPack : apply default value if not defined
175  if ( [ X${config_Post_LightRestartPack} = X${NULL_STR} ] || [ X${config_Post_LightRestartPack} = X ] ) ; then
176    config_Post_LightRestartPack=FALSE
177  fi
178
179  #====================================================
180  # Define StackFileLocation : directory where we store stack files
181  # Define StackFileName : stack file containing call tree and instrumentation
182  # Stack file containing call tree will be stored there.
183  if ( $DEBUG_debug ) ; then
184    StackFileLocation=${StackFileLocation:=${R_BUF_KSH}}
185    [ ! -d ${StackFileLocation} ] && mkdir -p ${StackFileLocation}
186    if [ X${TaskType} = Xcomputing ]; then
187      StackFileName=computing.stack.$$
188    elif [ X${TaskType} = Xpost-processing ]; then
189      StackFileName=${Script_Post_Output}.stack.$$
190    elif [ X${TaskType} = Xchecking ]; then
191      StackFileName=checking.stack.$$
192    else
193      IGCM_debug_Exit "IGCM_config_CommonConfiguration unknown TaskType : ${TaskType}"
194      IGCM_debug_Verif_Exit
195    fi
196
197    # This boolean will trigger the filling of the stack
198    # Only now we know where things should be ...
199    # We don't fill the stack when we perform checking task
200    if [ ! X${TaskType} = Xchecking ] ; then
201      ActivateStackFilling=true
202    fi
203  fi
204
205  IGCM_debug_PopStack "IGCM_config_CommonConfiguration"
206}
207
208#===================================
209function IGCM_config_Initialize
210{
211  IGCM_debug_PushStack "IGCM_config_Initialize"
212
213  # Debug Print :
214  echo
215  IGCM_debug_Print 1 "IGCM_config_Initialize"
216
217  # Test modipsl tree existence.
218  IGCM_sys_TestDir ${MODIPSL}
219  [ $? != 0 ] && IGCM_debug_Exit "IGCM_sys_TestDir"
220  IGCM_sys_TestDir ${libIGCM}
221  [ $? != 0 ] && IGCM_debug_Exit "IGCM_sys_TestDir"
222  IGCM_sys_TestDir ${R_EXE}
223  [ $? != 0 ] && IGCM_debug_Exit "IGCM_sys_TestDir"
224  IGCM_sys_TestDir ${SUBMIT_DIR}
225  [ $? != 0 ] && IGCM_debug_Exit "IGCM_sys_TestDir"
226
227  if ( $DEBUG_debug ) ; then
228    echo "Keep trace of inital SUBMIT_DIR : "
229    ls -lta ${SUBMIT_DIR}
230  fi
231
232  #==================================
233  # Read ListOfComponents section:
234  echo
235  IGCM_debug_Print 1 "DefineArrayFromSection : ListOfComponents"
236
237  IGCM_card_DefineArrayFromSection ${SUBMIT_DIR}/config.card ListOfComponents
238  for comp in ${config_ListOfComponents[*]} ; do
239    IGCM_card_DefineArrayFromOption ${SUBMIT_DIR}/config.card ListOfComponents ${comp}
240  done
241  IGCM_debug_Print 3 ${config_ListOfComponents[*]}
242
243  #==================================
244  # Read Executable section:
245  IGCM_card_DefineArrayFromSection   ${SUBMIT_DIR}/config.card Executable
246
247  #==================================
248  # Read Restarts section:
249  # Restarts : Gerneral rule or local for each component.
250  echo
251  IGCM_debug_Print 1 "DefineArrayFromOption : config_Restarts"
252
253  IGCM_card_DefineArrayFromSection ${SUBMIT_DIR}/config.card Restarts
254  for option in ${config_Restarts[*]} ; do
255    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/config.card Restarts ${option}
256    eval auxprint=\${config_Restarts_${option}}
257    IGCM_debug_Print 3 "${option} : ${auxprint}"
258  done
259
260  #==================================
261  # Define Job Outputs Name
262  echo
263  IGCM_debug_Print 2 "Define Script_Output_Prefix and Exe_Output"
264  Script_Output_Prefix=${config_UserChoices_Script_Output_Prefix:='Script_Output'}
265  IGCM_debug_Print 3 "Script_Output_Prefix = ${Script_Output_Prefix}"
266  Exe_Output=out_execution
267  IGCM_debug_Print 3 "Exe_Output           = ${Exe_Output}"
268
269  #===================================================================#
270  # Prepare variables available for ${COMP}.card and ${COMP}.driver   #
271  #             But available to any son functions                    #
272  #===================================================================#
273
274  # Convert yyyy-mm-dd date to gregorian yyyymmdd
275  DateBegin=$( IGCM_date_ConvertFormatToGregorian ${config_UserChoices_DateBegin} )
276  DateEnd=$(   IGCM_date_ConvertFormatToGregorian ${config_UserChoices_DateEnd}   )
277
278  # Period Length In Days between DateBegin and DateEnd
279  (( ExperienceLengthInDays=$( IGCM_date_DaysBetweenGregorianDate ${DateEnd} ${DateBegin} )  + 1 ))
280  if [ ${ExperienceLengthInDays} -lt 0 ] ; then
281    IGCM_debug_Print 1 "Problem with dates in config.card : ${DateEnd} < ${DateBegin} ! You must check that."
282    IGCM_debug_Exit "IGCM_config_Initialize" " Wrong Dates."
283    IGCM_debug_Verif_Exit
284  fi
285
286  # Day and Year of Initial State (Given in julian format)
287  InitDay=$(( $( IGCM_date_ConvertGregorianDateToJulian $DateBegin ) % 1000 ))
288  InitYear=$(( $( IGCM_date_ConvertGregorianDateToJulian $DateBegin ) / 1000 ))
289
290  #================================================================#
291  #                  Test and Prepare directories                  #
292  #================================================================#
293
294  # ==> 4 kinds of input files :
295  #     1) R_INIT  : Initial State Files   (Etat0, carteveg)
296  #     2) R_BC    : Boundary Conditions   (Forcages, lai)
297  #     3) Parameters files (allready define through ${SUBMIT_DIR})
298  #     4) Restarts files   (allready define in IGCM_config_Initialize)
299
300  # Here we offer the possibility to redefine R_INIT, R_BC
301  # and PeriodNb through config.card
302  R_INIT=${config_UserChoices_R_INIT:=${R_IN}/INIT}
303  echo
304  IGCM_debug_Print 2 "(Re)Define R_INIT, R_BC and PeriodNb"
305  IGCM_debug_Print 3 "R_IN=${R_IN}"
306  IGCM_debug_Print 3 "R_INIT=${R_INIT}"
307  R_BC=${config_UserChoices_R_BC:=${R_IN}/BC}
308  IGCM_debug_Print 3  "R_BC=${R_BC}"
309  PeriodNb=${config_UserChoices_PeriodNb:=${PeriodNb}}
310  IGCM_debug_Print 3  "Loop in main Job with ${PeriodNb} period(s)"
311
312  # SD ADA SPECIFIC #
313  #      TO FIX     #
314  #IGCM_sys_TestDirArchive ${R_IN}
315  #[ $? != 0 ] && IGCM_debug_Exit "IGCM_sys_TestDirArchive"
316
317  if ( ${FirstInitialize} ) ; then
318    IGCM_sys_MkdirArchive   ${R_SAVE}
319    [ ! ${config_Post_PackFrequency} = NONE ] && IGCM_sys_Mkdir ${R_BUFR}
320  else
321    IGCM_sys_TestDirArchive ${R_SAVE}
322    [ $? != 0 ] && IGCM_debug_Exit "IGCM_sys_TestDirArchive ${R_SAVE}"
323
324    if [ ! ${config_Post_PackFrequency} = NONE ] ; then
325      IGCM_sys_TestDir ${R_BUFR}
326      [ $? != 0 ] && IGCM_debug_Exit "IGCM_sys_TestDir ${R_BUFR}"
327    fi
328
329    # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
330    IGCM_config_StateCheck
331
332    # And EXIT if not OK
333    IGCM_debug_Verif_Exit
334  fi
335
336  #====================================================
337  # Experience type : DEB(ug), DEV(elopment), RUN
338  if [ X${JobType} != XRUN ] ; then
339    echo
340    echo "===================================================="
341    echo "libIGCM JOB is NOT in RUN type mode."
342    echo "!! OUTPUT files will NOT be PROTECTED !!"
343    echo "Be carefull : you can ERASE the result of this job !"
344
345    case ${JobType} in
346    DEB)
347      echo "DEBUG mode : activation of 'set -vx' mode."
348      echo "DEBUG mode : no protection for output files."
349      echo "DEBUG mode : if active force asynchronous rebuild frequency to PeriodLength frequency."
350      ;;
351    DEV)
352      echo "DEVelopment mode : no protection for output files."
353      echo "DEVelopment mode : if active force asynchronous rebuild frequency to PeriodLength frequency."
354      ;;
355    esac
356
357    if ( [ X${config_Post_RebuildFrequency} != XNONE ] && [ ${DRYRUN} -eq 0 ] ) ; then
358      if [ X${config_Post_RebuildFrequency} != X${config_UserChoices_PeriodLength} ] ; then
359        echo "------------"
360        echo "WARNING : Job is NOT in RUN mode then we will force REBUILD Frequency"
361        echo "          to PeriodLength : ${config_UserChoices_PeriodLength}"
362        echo "------------"
363        config_Post_RebuildFrequency=${config_UserChoices_PeriodLength}
364      fi
365    fi
366    echo "===================================================="
367    echo
368  fi
369
370  IGCM_debug_PopStack "IGCM_config_Initialize"
371}
372
373#===================================
374function IGCM_config_DaysInPeriodLength
375{
376  IGCM_debug_PushStack "IGCM_config_DaysInPeriodLength"
377
378  typeset i
379
380  # Determine number of day(s) in PeriodLength :
381  case ${config_UserChoices_PeriodLength} in
382  *Y|*y)
383    PeriodLengthInYears=$( echo ${config_UserChoices_PeriodLength} | sed -e 's/[yY]//' )
384    echo
385    IGCM_debug_Print 2 "Number of years for PeriodLength : ${PeriodLengthInYears}"
386    PeriodLengthInDays=0
387    i=0
388    until [ $i -ge $PeriodLengthInYears ] ; do
389      (( PeriodLengthInDays = PeriodLengthInDays + $( IGCM_date_DaysInYear $(( year + i )) ) ))
390      (( i=i+1 ))
391    done
392    ;;
393  *M|*m)
394    PeriodLengthInMonths=$( echo ${config_UserChoices_PeriodLength} | sed -e 's/[mM]//' )
395    echo
396    IGCM_debug_Print 2 "Number of months for PeriodLength : ${PeriodLengthInMonths}"
397    PeriodLengthInDays=0
398    i=0
399    until [ $i -ge $PeriodLengthInMonths ] ; do
400      if [ $(( 10#${month} + ${i} )) -lt 13 ] ; then
401        (( PeriodLengthInDays  = PeriodLengthInDays + $( IGCM_date_DaysInMonth $year $(( 10#${month} + ${i} )) ) ))
402      else
403        (( PeriodLengthInDays  = PeriodLengthInDays + $( IGCM_date_DaysInMonth $year $(( 10#${month} + ${i} - 12 )) ) ))
404      fi
405      (( i=i+1 ))
406    done
407    ;;
408  *D|*d)
409    PeriodLengthInMonths=0
410    PeriodLengthInDays=$( echo ${config_UserChoices_PeriodLength} | sed -e 's/[dD]//' )
411    echo
412    IGCM_debug_Print 2 "Number of days for PeriodLength : ${PeriodLengthInDays}";;
413  *)
414    IGCM_debug_Exit "IGCM_config_DaysInPeriodLength " ${config_UserChoices_PeriodLength} " invalid period length : choose in *Y, *M, *D."
415    IGCM_debug_Verif_Exit ;;
416  esac
417
418  IGCM_debug_PopStack "IGCM_config_DaysInPeriodLength"
419}
420
421#===================================
422function IGCM_config_DateCoherency
423{
424  IGCM_debug_PushStack "IGCM_config_DateCoherency"
425
426  echo
427  IGCM_debug_Print 1 "IGCM_config_DateCoherency"
428  echo
429
430  typeset Length VerifiedPeriodDateBegin VerifiedPeriodDateEnd
431
432  # check coherency between (PeriodDateBegin, PeriodDateEnd) and (DateBegin, CumulPeriod, PeriodLength)
433  # DateBegin + CumulPeriod*PeriodLength = PeriodDateBegin
434  echo
435
436  case ${config_UserChoices_PeriodLength} in
437  *Y|*y)
438    Length=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} $(( ${CumulPeriod} * ${PeriodLengthInYears} ))Y )
439    ;;
440  *M|*m)
441    Length=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} $(( ${CumulPeriod} * ${PeriodLengthInMonths} ))M )
442    ;;
443  *D|*d)
444    Length=$( IGCM_date_DaysInCurrentPeriod ${DateBegin} $(( ${CumulPeriod} * ${PeriodLengthInDays} ))D )
445    ;;
446  esac
447  VerifiedPeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate ${DateBegin} ${Length}-1 )
448
449  if [ ${VerifiedPeriodDateEnd} != ${PeriodDateEnd} ] ; then
450    IGCM_debug_Print 1 "From run.card PeriodDateEnd is not consistent with DateBegin and CumulPeriod."
451    IGCM_debug_Print 1 "We have DateBegin = ${DateBegin}"
452    IGCM_debug_Print 1 "We have CumulPeriod = ${CumulPeriod}"
453    IGCM_debug_Print 1 "We have PeriodDateEnd = ${PeriodDateEnd}"
454    IGCM_debug_Print 1 "We have VerifiedPeriodDateEnd = ${VerifiedPeriodDateEnd}"
455    IGCM_debug_Print 1 "You must have change run.card in an inconsistent way."
456
457    IGCM_debug_Exit "STOP here to avoid further issues."
458  fi
459
460  # PeriodDateBegin + PeriodLength = PeriodDateEnd
461  VerifiedPeriodDateBegin=$( IGCM_date_AddDaysToGregorianDate ${VerifiedPeriodDateEnd} $(( ${PeriodLengthInDays} * -1 )) )
462
463  IGCM_debug_PopStack "IGCM_config_DateCoherency"
464}
465
466#===================================
467function IGCM_config_StateCheck
468{
469  IGCM_debug_PushStack "IGCM_config_StateCheck"
470
471    #Test state of run in run.card
472    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration PeriodState
473
474    if [ ${run_Configuration_PeriodState} = "Fatal" ] ; then
475      echo
476      IGCM_debug_Print 1 "!! Error in run.card with PeriodState : " ${run_Configuration_PeriodState} "!!"
477      IGCM_debug_Print 1 "Check the overall status of your simulation by visiting this page:"
478      IGCM_debug_Print 1 "http://prodiguer-test-web.ipsl.fr/static/simulation.detail.html?uid=${simuid}"
479      IGCM_debug_Print 1 "Then try running ${libIGCM}/clean_PeriodLenght.job to clean latest failed period"
480      IGCM_debug_Print 1 "Or try running ${libIGCM}/clean_latestPackperiod.job to clean lastest pack period."
481      IGCM_debug_Print 1 "Or use ${libIGCM}/purge_simulation.job to delete the full simulation."
482      IGCM_debug_Exit
483    elif [ $( echo ${run_Configuration_PeriodState} | grep Fatal | wc -l ) -eq 1 ] ; then
484      echo
485      IGCM_debug_Print 1 "!! Error in run.card with PeriodState : " ${run_Configuration_PeriodState} "!!"
486      IGCM_debug_Print 1 "Compute jobs has been stop because at least the above mentionned post-processing jobs fails."
487      IGCM_debug_Print 1 "Check post-processing jobs carefully by visiting this page:"
488      IGCM_debug_Print 1 "http://prodiguer-test-web.ipsl.fr/static/simulation.detail.html?uid=${simuid}"
489      IGCM_debug_Print 1 "Please visit that page to see how to fix issues:"
490      IGCM_debug_Print 1 "https://forge.ipsl.jussieu.fr/igcmg_doc/wiki/DocGmonitor"
491      IGCM_debug_Print 1 "Then try running ${libIGCM}/clean_PeriodLenght.job to clean latest failed period"
492      IGCM_debug_Print 1 "Or try running ${libIGCM}/clean_latestPackperiod.job to clean latest pack period."
493      IGCM_debug_Print 1 "Or use ${libIGCM}/purge_simulation.job to delete the full simulation."
494      IGCM_debug_Exit
495    fi
496
497  IGCM_debug_PopStack "IGCM_config_StateCheck"
498}
499
500#===================================
501function IGCM_config_Check
502{
503  IGCM_debug_PushStack "IGCM_config_Check"
504
505  # If one of the following modulo is not zero :
506  # we will issue an error then explain and exit in
507  # AA_job IGCM_debug_Verif_Exit call before binary submission
508
509  echo
510  IGCM_debug_Print 1 "IGCM_config_Check"
511  echo
512
513  typeset i
514
515  # Check RebuildFrequency against key frequencies : PeriodLength ; PackFrequency ; TimeSeriesFrequency ; SeasonalFrequency
516  if ( [ ! X${config_Post_RebuildFrequency} = X${NULL_STR} ] && [ ! X${config_Post_RebuildFrequency} = XNONE ] ) ; then
517    AsynchronousRebuild=true
518    IGCM_debug_Print 1 "Asynchronous rebuild has been activated."
519    echo
520    # modulo (RebuildFrequency and PeriodLength/TimeSeriesFrequency/SeasonalFrequency) must be zero
521    IGCM_debug_Print 1 "Check coherence between RebuildFrequency and PeriodLength"
522    IGCM_post_CheckModuloFrequency config_Post_RebuildFrequency config_UserChoices_PeriodLength
523    IGCM_debug_Print 1 "Check coherence between PackFrequency and RebuildFrequency"
524    IGCM_post_CheckModuloFrequency config_Post_PackFrequency config_Post_RebuildFrequency
525    IGCM_debug_Print 1 "Check coherence between TimeSeriesFrequency and RebuildFrequency"
526    IGCM_post_CheckModuloFrequency config_Post_TimeSeriesFrequency config_Post_RebuildFrequency
527    IGCM_debug_Print 1 "Check coherence between SeasonalFrequency and RebuildFrequency"
528    IGCM_post_CheckModuloFrequency config_Post_SeasonalFrequency config_Post_RebuildFrequency
529  else
530    AsynchronousRebuild=false
531    IGCM_debug_Print 1 "Asynchronous rebuild has not been activated"
532    IGCM_debug_Print 1 "Proceed with standard post-treatment pathway"
533    echo
534    #modulo (PeriodLength and TimeSeriesFrequency/SeasonalFrequency) must be zero
535    IGCM_debug_Print 1 "Check coherence between TimeSeriesFrequency and PeriodLength"
536    IGCM_post_CheckModuloFrequency config_Post_TimeSeriesFrequency config_UserChoices_PeriodLength
537    IGCM_debug_Print 1 "Check coherence between SeasonalFrequency and PeriodLength"
538    IGCM_post_CheckModuloFrequency config_Post_SeasonalFrequency   config_UserChoices_PeriodLength
539  fi
540
541  # Check PackFrequency against other key frequencies
542  # Modulo (PackFrequency and TimeSeriesFrequency/SeasonalFrequency and PeriodLenght) must be zero
543  if ( [ ! X${config_Post_PackFrequency} = X${NULL_STR} ] && [ ! X${config_Post_PackFrequency} = XNONE ] ) ; then
544    Pack=true
545    #
546    IGCM_debug_Print 1 "Check coherence between PackFrequency and PeriodLength"
547    IGCM_post_CheckModuloFrequency config_Post_PackFrequency config_UserChoices_PeriodLength
548    IGCM_debug_Print 1 "Check coherence between TimeSeriesFrequency and PackFrequency"
549    IGCM_post_CheckModuloFrequency config_Post_TimeSeriesFrequency config_Post_PackFrequency
550    IGCM_debug_Print 1 "Check coherence between SeasonalFrequency and PackFrequency"
551    IGCM_post_CheckModuloFrequency config_Post_SeasonalFrequency config_Post_PackFrequency
552  else
553    Pack=false
554  fi
555
556  # modulo (TimeSeriesFrequency and all Chunck2D) must be zero
557  NbJob=${#CHUNCK2D_SIZE[@]}
558  i=0
559  until [ $i -ge $NbJob ]; do
560    value=${CHUNCK2D_SIZE[${i}]}
561    IGCM_debug_Print 1 "Check coherence between ${CHUNCK2D_NAME[${i}]} Chunck2D frequency and TimeSeriesFrequency"
562    IGCM_post_CheckModuloFrequency value config_Post_TimeSeriesFrequency
563    case ${value} in
564    *Y|*y) ;;
565    *)
566      IGCM_debug_Print 1 "All ChunckJob2D frequency must be expressed in year *Y|*y in comp.card"
567      IGCM_debug_Exit "This will stop the job" ;;
568    esac
569    (( i=i+1 ))
570  done
571
572  # modulo (TimeSeriesFrequency and all Chunck3D) must be zero
573  NbJob=${#CHUNCK3D_SIZE[@]}
574  i=0
575  until [ $i -ge $NbJob ]; do
576    value=${CHUNCK3D_SIZE[${i}]}
577    IGCM_debug_Print 1 "Check coherence between ${CHUNCK3D_NAME[${i}]} Chunck3D frequency and TimeSeriesFrequency"
578    IGCM_post_CheckModuloFrequency value config_Post_TimeSeriesFrequency
579    case ${value} in
580    *Y|*y) ;;
581    *)
582      IGCM_debug_Print 1 "All ChunckJob3D frequency must be expressed in year *Y|*y in comp.card"
583      IGCM_debug_Exit "This will stop the job" ;;
584    esac
585    (( i=i+1 ))
586  done
587
588  # check to be sure there is enough space on temporary filesystems to run
589  echo
590  IGCM_debug_Print 1 "Check if there is enough space on temporary filesystem"
591  IGCM_sys_check_quota
592
593  # check to be sure that RUN_DIR_PATH, that will be removed is not pointing to an important directory
594  echo
595  IGCM_debug_Print 1 "Check where RUN_DIR_PATH variable is pointing to"
596  IGCM_sys_check_path
597
598
599  IGCM_debug_PopStack "IGCM_config_Check"
600}
601
602#===================================
603function IGCM_config_ConfigureExecution
604{
605  IGCM_debug_PushStack " IGCM_config_ConfigureExecution"
606
607  #echo
608  IGCM_debug_Print 1 " IGCM_config_ConfigureExecution"
609  #echo
610
611  typeset ExeNameIn ExeNameFirst CompNameFirst configCardPath comp i
612  typeset tempvar tempvarMPI tempvarNOD NbElts NbExec
613
614  # config.card path
615  configCardPath=$1
616
617  coreNumber=0
618  mpiTasks=0
619  openMPthreads=0
620  NbExec=0
621
622  OK_PARA_MPI=false
623  OK_PARA_OMP=false
624  OK_PARA_NOD=false
625  OK_PARA_MPMD=false
626
627  for comp in ${config_ListOfComponents[*]} ; do
628
629    # Manage component executable
630    IGCM_card_DefineArrayFromOption ${configCardPath} Executable ${comp}
631
632    eval ExeNameIn=\${config_Executable_${comp}[0]}
633
634    # NO order in config.card for parallelized values !
635    # just use suffix : MPI , OMP and NOD (for number of NODes.)
636
637    # NOD is the number of NODes allocated
638    eval ${comp}_PROC_NOD=0
639
640    # MPI is the number of MPI processus per nodes
641    eval ${comp}_PROC_MPI=0
642
643    # OMP is the number of OpenMP threads per MPI processus
644    eval ${comp}_PROC_OMP=0
645
646    # Only if we really have an executable for the component :
647    if ( [ "X${ExeNameIn}" != X\"\" ] && [ "X${ExeNameIn}" != "Xinca.dat" ] ) ; then
648
649      IGCM_debug_Print 1 ${comp}
650
651      # Keep the first executable found and the first CompName
652      ExeNameFirst=${ExeNameIn}
653      CompNameFirst=${comp}
654
655      # Are we a second executable?
656      (( NbExec = NbExec + 1 ))
657
658      # set 1 MPI task, 1 OpenMP thread and 1 node as default
659      eval ${comp}_PROC_MPI=1
660      eval ${comp}_PROC_OMP=1
661      eval ${comp}_PROC_NOD=1
662
663      eval NbElts=\${#config_Executable_${comp}[@]}
664
665      if [ ${NbElts} -gt 2 ] ; then
666        #
667        # CURRENT METHOD TO SPECIFY MPI AND OMP RESSOURCES
668        #
669        i=2
670        while [ ${i} -lt ${NbElts} ] ; do
671          eval tempvar=\${config_Executable_${comp}[${i}]}
672          IGCM_debug_Print 2 ${tempvar}
673
674          if [ X${tempvar} = X ] ; then
675            IGCM_debug_Print 2 "Error reading MPI/OMP parameters !!!"
676            IGCM_debug_Exit "Check your config.card. Exit now"
677            IGCM_debug_Verif_Exit
678          fi
679
680          case ${tempvar} in
681          *[mM][pP][iI]*)
682            # Read MPI parameter for composante
683            eval ${comp}_PROC_MPI=$( echo ${tempvar} | tr '[a-z]' '[A-Z]' | sed -e "s/MPI//" )
684            OK_PARA_MPI=true;;
685          *[oO][mM][pP]*)
686            # Read OMP parameter for composante
687            eval ${comp}_PROC_OMP=$( echo ${tempvar} | tr '[a-z]' '[A-Z]' | sed -e "s/OMP//" )
688            ;;
689          *[nN][oO][dD]*)
690            # Read NOD (NumBer of Nodes) parameter for composante
691            eval ${comp}_PROC_NOD=$( echo ${tempvar} | tr '[a-z]' '[A-Z]' | sed -e "s/NOD//" )
692            OK_PARA_NOD=true
693            OK_PARA_MPI=true
694            ;;
695          esac
696          (( i = i + 1 ))
697        done
698      else
699        #
700        # BACKWARD COMPATIBILITY NOT SUPPORTED ANYMORE
701        #
702        IGCM_debug_Exit "You are using a deprecated ressources specification mechanism in your config.card"
703        IGCM_debug_Exit "Please check : https://forge.ipsl.jussieu.fr/igcmg_doc/wiki/DocEsetup#ThesectionExecutable"
704        IGCM_debug_Exit "Please modify ${configCardPath}"
705        exit
706      fi
707      if [ ${comp}_PROC_NOD -gt 1 ] ; then
708            if ( [ ${comp}_PROC_MPI -gt 1 ] && [ ${comp}_PROC_OMP -gt 1 ] ) ; then
709              IGCM_debug_Print 2 "Error using MPI/OMP/NOD parameters !!!"
710              IGCM_debug_Exit "It is not allowed to use MPI and OMP and NOD parameters for the same component"
711              IGCM_debug_Exit "Check your config.card. Exit now"
712              IGCM_debug_Verif_Exit
713            fi
714            if [ "${comp}" != "IOS" ] ; then
715              IGCM_debug_Print 2 "Error using NOD parameter !!!"
716              IGCM_debug_Exit "NOD parameter is only available for IOS component "
717              IGCM_debug_Exit "Check your config.card. Exit now"
718              IGCM_debug_Verif_Exit
719            fi
720      fi
721
722      eval tempvarMPI=\${${comp}_PROC_MPI}
723      eval tempvarNOD=\${${comp}_PROC_NOD}
724      eval tempvarOMP=\${${comp}_PROC_OMP}
725
726      # set OMP mode if more than 1 OMP thread.
727      [ ${tempvarOMP} -ge 2 ] && OK_PARA_OMP=true
728
729      # Number of OMP threads
730      [ ${openMPthreads} -lt ${tempvarOMP} ] && openMPthreads=${tempvarOMP}
731
732      # SUM UP NUMBER OF CORES
733      if [ ${comp}_PROC_NOD -gt 1 ] ; then 
734          (( coreNumber = coreNumber + tempvarNOD * NB_CORE_PER_NODE ))
735      else
736          (( coreNumber = coreNumber + tempvarMPI * tempvarNOD * tempvarOMP ))
737      fi
738      # SUM UP NUMBER OF MPI TASKS
739      (( mpiTasks = mpiTasks + tempvarMPI * tempvarNOD ))
740    fi
741  done
742
743  # MANDATORY FOR THE OPA9.DRIVER. USED TO EDIT OPA NAMELIST
744  # WE SHOULD PLANIFY NUM_PROC_??? DEPRECATION
745  NUM_PROC_CPL=${CPL_PROC_MPI}
746  NUM_PROC_OCE=${OCE_PROC_MPI}
747  NUM_PROC_ATM=${ATM_PROC_MPI}
748
749  # set MPMD mode if more than 2 executable names.
750  [ ${NbExec} -ge 2 ] && OK_PARA_MPMD=true 
751
752  # Define the execution type we are running in
753  if ( ${OK_PARA_MPMD} ) ; then
754    if ( ${OK_PARA_MPI} ) ; then
755      # MPMD always implies MPI
756      executionType=1
757    fi
758    if ( ${OK_PARA_OMP} ) ; then
759      # MPMD + MPI/OMP
760      executionType=2
761    fi
762  else
763    if ( ( ${OK_PARA_MPI} ) && ( ${OK_PARA_OMP} ) ) ; then
764      # SPMD + MPI/OMP
765      executionType=3
766    elif ( ( ${OK_PARA_MPI} ) && ( ! ${OK_PARA_OMP} ) ) ; then
767      # SPMD + MPI only
768      executionType=4
769    elif ( ( ! ${OK_PARA_MPI} ) && ( ${OK_PARA_OMP} ) ) ; then
770      # SPMD + OMP only
771      executionType=5
772    elif ( ( ! ${OK_PARA_MPI} ) && ( ! ${OK_PARA_OMP} ) ) ; then
773      # SEQUENTIAL THEN
774      executionType=6
775      coreNumber=1
776    fi
777  fi
778
779  IGCM_debug_Print 1 "MPI/OMP treatment coreNumber = ${coreNumber}"
780  IGCM_debug_Print 1 "MPI/OMP treatment mpiTasks = ${mpiTasks}"
781  IGCM_debug_Print 1 "MPI/OMP treatment openMPthreads = ${openMPthreads}"
782  IGCM_debug_Print 1 "MPI/OMP treatment executionType = ${executionType}"
783
784  IGCM_debug_PopStack "IGCM_config_ConfigureExecution"
785}
786
787#===================================
788function IGCM_config_PeriodStart
789{
790  IGCM_debug_PushStack "IGCM_config_PeriodStart"
791
792  echo
793  IGCM_debug_Print 1 "IGCM_config_PeriodStart"
794  echo
795
796  if ( ${FirstInitialize} ) ; then
797    #================================================#
798    #         Initialize date/period information     #
799    #================================================#
800
801    IGCM_date_GetYearMonthDay ${DateBegin} year month day
802    IGCM_config_DaysInPeriodLength
803
804    PeriodDateBegin=${DateBegin}
805    PeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate ${DateBegin} $(( ${PeriodLengthInDays} - 1 )) )
806    CumulPeriod=1
807
808    #=================================================#
809    #              Write updated run.card             #
810    #=================================================#
811
812    #Correct run.card Configuration for this period
813    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateBegin ${PeriodDateBegin}
814    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateEnd ${PeriodDateEnd}
815    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration CumulPeriod ${CumulPeriod}
816    if [ X$( grep "SubmitPath" ${SUBMIT_DIR}/run.card ) != X ] ; then
817      IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration SubmitPath ${SUBMIT_DIR}
818    fi
819
820    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Running"
821
822  else
823    #================================================#
824    #         The file run.card allready exist       #
825    #================================================#
826
827    # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
828    IGCM_config_StateCheck
829    # And EXIT if not OK
830    IGCM_debug_Verif_Exit
831
832    #===================================#
833    #        Read updated run.card      #
834    #===================================#
835
836    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration PeriodDateBegin
837    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration PeriodDateEnd
838    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration CumulPeriod
839
840    PeriodDateBegin=$( IGCM_date_ConvertFormatToGregorian ${run_Configuration_PeriodDateBegin} )
841    PeriodDateEnd=$( IGCM_date_ConvertFormatToGregorian ${run_Configuration_PeriodDateEnd} )
842    CumulPeriod=${run_Configuration_CumulPeriod}
843
844    LastPeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate $( IGCM_date_ConvertFormatToGregorian ${PeriodDateBegin} ) -1 )
845
846    if [ ${Period} = 1 ]; then
847      # save last Job output and current run.card
848      typeset Potential
849      IGCM_sys_Cd ${SUBMIT_DIR}
850      #
851      IGCM_debug_Print 2 "Save previous ksh job output"
852      for Potential in $( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.[0-9][0-9][0-9][0-9][0-9][0-9] ) ; do
853        if [ X${Pack} = Xtrue ] ; then
854          ( IGCM_sys_TestFileBuffer  ${R_BUF_KSH}/${Potential} ) || IGCM_sys_Cp ${Potential} ${R_BUF_KSH}/${Potential}.$$
855        else
856          ( IGCM_sys_TestFileArchive ${R_OUT_KSH}/${Potential} ) || IGCM_sys_Put_Out ${Potential} ${R_OUT_KSH}/${Potential}.$$ NOMOVE
857          IGCM_debug_Print 1 "Save of previous ksh job output is not done for Pack=false"
858        fi
859      done
860
861      #
862      IGCM_debug_Print 2 "Save current run.card"
863      IGCM_card_CheckConflict run.card
864
865      if [ X${Pack} = Xtrue ] ; then
866        IGCM_sys_Cp ${SUBMIT_DIR}/run.card ${R_BUF_KSH}/run.card
867      else
868        IGCM_sys_Put_Out ${SUBMIT_DIR}/run.card ${R_OUT_KSH}/run.card NOMOVE
869        IGCM_debug_Print 1 "Save of run.card is not done for Pack=false"
870      fi
871      #
872      IGCM_sys_Cd ${RUN_DIR}
873    else
874      unset FileToBeDeleted
875    fi
876
877    # Determine number of day(s) in PeriodLength
878    IGCM_date_GetYearMonthDay $PeriodDateBegin year month day
879    IGCM_config_DaysInPeriodLength
880
881    # Check coherency between (PeriodDateBegin, PeriodDateEnd) and (DateBegin, CumulPeriod, PeriodLength)
882    IGCM_config_DateCoherency
883    # And EXIT if not OK
884    IGCM_debug_Verif_Exit
885
886    # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
887    IGCM_config_StateCheck
888    # And EXIT if not OK
889    IGCM_debug_Verif_Exit
890
891    # We can say we are "Running" now.
892    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Running"
893  fi
894
895  # BEGIN: SHOULD GO IN A FUNCTION FROM libIGCM_date.ksh
896  # Compute year_m1 and year_p1 (year minus 1Y and year plus 1Y)
897  year_m1=$(( year - 1 ))
898  year_p1=$(( year + 1 ))
899  # Compute month_m1 (month minus 1M)
900  # Compute yyyymm_m1 (yyyymm minus 1M)
901  month_m1=$(( 10#${month} - 1 ))
902  if [ ${month_m1} = 0 ]; then
903    month_m1=12
904    yyyymm_m1=${year_m1}12
905  elif [ ${month_m1} -le 9 ]; then
906    month_m1=0${month_m1}
907    yyyymm_m1=${year}${month_m1}
908  else
909    yyyymm_m1=${year}${month_m1}
910  fi
911  # Compute month_p1 (month plus 1M)
912  # Compute yyyymm_p1 (yyyymm plus 1M)
913  month_p1=$(( 10#${month} + 1 ))
914  if [ ${month_p1} = 13 ]; then
915    month_p1=01
916    yyyymm_p1=${year_p1}01
917  elif [ ${month_p1} -le 9 ]; then
918    month_p1=0${month_p1}
919    yyyymm_p1=${year}${month_p1}
920  else
921    yyyymm_p1=${year}${month_p1}
922  fi
923
924  #===================================================================#
925  # Calculate CyclicYear to be used for looping over a given forcing  #
926  # period. Add CyclicBegin and CyclicEnd in config.card UserChoices. #
927  #===================================================================#
928
929  # To use the variable CyclicYear, one must add in config.card CyclicBegin and CyclicEnd.
930  # CyclicBegin is the first year in the cycle. CyclicEnd is the last year included in the cycle.
931  if ( [ ! X${config_UserChoices_CyclicBegin} = X ] && [ ! X${config_UserChoices_CyclicEnd} = X ] ) ; then
932    CycleNb=$(( ${config_UserChoices_CyclicEnd} - ${config_UserChoices_CyclicBegin} + 1 ))
933    CyclicYear_p1=NOTDEFINED
934
935    # For current year
936    yeartmp=$year
937    diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
938    while [ $diffy -lt 0 ] ; do
939      yeartmp=$(( ${yeartmp} + ${CycleNb} ))
940      diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
941    done
942    CyclicYear=$(( ( ${diffy} % ${CycleNb} ) + ${config_UserChoices_CyclicBegin} ))
943
944    # For next coming year
945    yeartmp=$(( $year + 1 ))
946    diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
947    while [ $diffy -lt 0 ] ; do
948      yeartmp=$(( ${yeartmp} + ${CycleNb} ))
949      diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
950    done
951    CyclicYear_p1=$(( ( ${diffy} % ${CycleNb} ) + ${config_UserChoices_CyclicBegin} ))
952
953    IGCM_debug_Print 1 "CyclicYear   = ${CyclicYear}, CyclicYear_p1 = ${CyclicYear_p1}, current year=$year"
954  else
955    CyclicYear="ERROR_CyclicYear_Variable_Not_Defined"
956    CyclicYear_p1="ERROR_CyclicYear_p1_Variable_Not_Defined"
957    IGCM_debug_Print 1 "CyclicYear wont be use without adding CyclicBegin and CyclicEnd in config.card"
958  fi
959
960  # END: SHOULD GO IN A FUNCTION FROM libIGCM_date.ksh
961
962  #===================================================================#
963  # Prepare variables available for ${COMP}.card and ${COMP}.driver   #
964  #             But available to any son functions                    #
965  #===================================================================#
966
967  # Period Length In Days between DateBegin and DateCurrent (at end of period == PeriodDateEnd !)
968  (( SimulationLengthInDays = $( IGCM_date_DaysBetweenGregorianDate ${PeriodDateEnd} ${DateBegin} ) + 1 ))
969
970  # Debug Print :
971  echo
972  IGCM_debug_Print 1 "IGCM_config_PeriodStart : Before Execution"
973  IGCM_debug_Print 1 "Year of simulation      : ${year}"
974  IGCM_debug_Print 1 "Month of simulation     : ${month}"
975  IGCM_debug_Print 1 "PeriodLengthInDays      : ${PeriodLengthInDays}"
976  IGCM_debug_Print 1 "PeriodDateBegin         : ${PeriodDateBegin}"
977  IGCM_debug_Print 1 "PeriodDateEnd           : ${PeriodDateEnd}"
978  IGCM_debug_Print 1 "SimulationLengthInDays  : ${SimulationLengthInDays}"
979  IGCM_debug_Print 1 "ExperienceLengthInDays  : ${ExperienceLengthInDays}"
980
981  #================================================================#
982  #         Prepare variables available for comp_finalyze          #
983  #================================================================#
984
985  # Period for save files
986  DatesPeriod=${PeriodDateBegin}_${PeriodDateEnd}
987
988  # Prefix for save files of this period
989  PREFIX=${config_UserChoices_JobName}_${DatesPeriod}
990
991  # List of files that will be deleted in RUN_DIR after run
992  [ -f stack ] && FileToBeDeleted[0]="stack"
993
994  # Test if the same run as already been saved :
995  if [ X${JobType} = XRUN ] ; then
996    if [ ${DRYRUN} -le 0 ] ; then
997      if ( IGCM_sys_TestFileBuffer ${R_BUF_KSH}/${PREFIX}_${Exe_Output} ) ; then
998        IGCM_debug_Exit "IGCM_config_PeriodStart" "You are currently re-running an old job."
999        IGCM_debug_Print 1 "Because of readonly permissions, you can't re-run a job when saved files"
1000        IGCM_debug_Print 1 " are still in the ARCHIVE directory. You must deleted those files, or "
1001        IGCM_debug_Print 1 " the whole ${R_SAVE} tree. See different clean_*.job in ${libIGCM} directory."
1002        IGCM_debug_Print 1 " This exit has been initiated because at least ${R_BUF_KSH}/${PREFIX}_${Exe_Output} exists."
1003        IGCM_debug_Verif_Exit
1004      fi
1005    fi
1006  else
1007    if ( IGCM_sys_TestFileBuffer ${R_BUF_KSH}/${PREFIX}_${Exe_Output} ) ; then
1008      IGCM_debug_Print 1 "IGCM_config_PeriodStart" "RErun an old job. Allowed in DEBUG or DEV mode."
1009    fi
1010  fi
1011
1012  #================================================================#
1013  #       Prepare variables available for binary execution         #
1014  #       Call function for creation of run script                 #
1015  #       Only done once per job                                   #
1016  #================================================================#
1017
1018  if [ ${Period} -eq 1 ]; then
1019    # Define the execution context (MPMD, SPMD, MPI/OMP ...)
1020    IGCM_config_ConfigureExecution ${SUBMIT_DIR}/config.card
1021    # Create the execution script for the current context
1022    IGCM_sys_build_execution_scripts
1023  fi
1024
1025  ExecutionFail=false
1026
1027  # Update the rabbitMQ queue
1028  IGCM_debug_BigBro_Update
1029
1030  IGCM_debug_PopStack "IGCM_config_PeriodStart"
1031}
1032
1033#===================================
1034function IGCM_config_SaveSourceModifications
1035{
1036  IGCM_debug_PushStack "IGCM_config_SaveSourceModifications"
1037
1038  typeset ExeOutDateMax listVarEnv
1039  ExeOutDateMax=$1
1040
1041  listVarEnv="ExeOutDateMax,R_OUT_EXE,PREFIX,SUBMIT_DIR"
1042  IGCM_sys_RshMaster "\
1043    . ${libIGCM}/libIGCM_sys/libIGCM_sys.ksh; \
1044    export ExeOutDateMax=${ExeOutDateMax};\
1045    export R_OUT_EXE=${R_OUT_EXE};\
1046    export PREFIX=${PREFIX};\
1047    export SUBMIT_DIR=${SUBMIT_DIR};\
1048    export listVarEnv=${listVarEnv};\
1049    Script_Output=out_SaveSourceModifications;\
1050    IGCM_sys_Qsub ${libIGCM}/SaveSourceModifications.job ${ExeOutDateMax} ${R_OUT_EXE} ${PREFIX} ${SUBMIT_DIR}"
1051
1052  IGCM_debug_PopStack "IGCM_config_SaveSourceModifications"
1053}
1054
1055#===================================
1056function IGCM_config_PeriodEnd
1057{
1058  IGCM_debug_PushStack "IGCM_config_PeriodEnd"
1059
1060  echo
1061  IGCM_debug_Print 1 "IGCM_config_PeriodEnd"
1062  echo
1063
1064  if [ ${DRYRUN} -le 1 ] ; then
1065
1066    IGCM_debug_Print 1 "Check components binary : size and creation date"
1067
1068    typeset LS_comp LS_bin ExeDate ExeCpuLog NextExeSize LastCompExeSize
1069    typeset comp i
1070    typeset ExeNameIn ExeNameOut UpdateExe ExeSecDateMax
1071
1072    #==================================#
1073    #        Get last Exe Size         #
1074    #==================================#
1075
1076    (( i=0 ))
1077    if ( ${FirstInitialize} ) ; then
1078      run_Log_LastExeSize=""
1079      for comp in ${config_ListOfComponents[*]} ; do
1080        run_Log_LastExeSize[$i]=0
1081        (( i=i+1 ))
1082      done
1083    else
1084      IGCM_card_DefineArrayFromOption ${SUBMIT_DIR}/run.card Log LastExeSize
1085    fi
1086    #==================================#
1087    #         And Build ExeDate        #
1088    #==================================#
1089
1090    # ExeDate = ATM_Jun_12_09:34-SRF_Jun_12_09:34-OCE_Jun_12_09:34-ICE_Jun_12_09:34-CPL_Jun_12_09:33
1091    # Would be nice to have next line but no way to format ls output (need to ls -l --time-style "+%Y-%m-%dT%H:%M")
1092    # ExeDate = ATM_2009-06-12T09:34+SRF_2009-06-12T09:34+OCE_2009-06-12T09:34+ICE_2009-06-12T09:34+CPL_2009-06-12T09:34
1093    ExeDate=""
1094    NextExeSize="( "
1095    (( i=0 ))
1096    UpdateExe=false
1097    (( ExeSecDateMax = 0 ))
1098    for comp in ${config_ListOfComponents[*]} ; do
1099
1100      IGCM_debug_Print 3 ${comp}
1101
1102      eval ExeNameIn=\${config_Executable_${comp}[0]}
1103      eval ExeNameOut=\${config_Executable_${comp}[1]}
1104      # Only if we really have an executable for the component :
1105      if [ X${ExeNameIn} = X\"\" ] ; then
1106        # If there is no exe file for this component
1107        (( ExeSize=0 ))
1108      else
1109        LS_bin=${R_EXE}/${ExeNameIn}
1110        IGCM_sys_FileSize ${LS_bin} ExeSize
1111
1112        set +A LS_comp -- $( LC_TIME=en_US ls -l ${LS_bin} )
1113        if [ X${ExeDate} = X ] ; then
1114          # First component exe date
1115          ExeDate=${comp}_${LS_comp[5]}_${LS_comp[6]}
1116        else
1117          ExeDate=${ExeDate}-${comp}_${LS_comp[5]}_${LS_comp[6]}
1118        fi
1119        ExeDate=${ExeDate}_${LS_comp[7]}
1120      fi
1121
1122      if [ ${i} -eq 0 ] ; then
1123        # First component
1124        NextExeSize="( "${ExeSize}
1125      else
1126        NextExeSize=${NextExeSize}", "${ExeSize}
1127      fi
1128      LastCompExeSize=${run_Log_LastExeSize[$i]}
1129      (( i=i+1 ))
1130
1131      if [ ${ExeSize} -ne ${LastCompExeSize} ] ; then
1132        if ( ${FirstInitialize} ) ; then
1133          IGCM_debug_Print 1 "Save first ${ExeNameIn} in ${R_OUT_EXE} !"
1134        else
1135          IGCM_debug_Print 1 "${ExeNameIn} has changed in ${R_EXE} !"
1136          IGCM_debug_Print 1 "Save latest ${ExeNameIn} in ${R_OUT_EXE} !"
1137          FileToBeDeleted[${#FileToBeDeleted[@]}]=${ExeNameOut}
1138        fi
1139        IGCM_sys_Put_Out ${ExeNameOut} ${R_OUT_EXE}/${PREFIX}_${ExeNameIn} rw
1140        UpdateExe=true
1141
1142        # SD : switch off for now
1143        #IGCM_sys_GetDate_FichWork ${LS_bin} ExeSecDate
1144        #if [ $ExeSecDateMax -lt $ExeSecDate ] ; then
1145        #  ExeSecDateMax=$ExeSecDate
1146        #fi
1147      fi
1148    done
1149
1150    # SD : switch off for now
1151    #if ( ${UpdateExe} ) ; then
1152    #  echo "Launch SaveSourceModifications."
1153    #  IGCM_config_SaveSourceModifications ${ExeSecDateMax}
1154    #fi
1155
1156    NextExeSize=${NextExeSize}" )"
1157    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Log LastExeSize "${NextExeSize}"
1158
1159    if [ ${DRYRUN} -le 1 ] ; then
1160      tail -1500 ${Exe_Output} > ${Exe_Output}_tail.txt
1161      ExeCpuLog=$( gawk -f ${libIGCM}/libIGCM_sys/IGCM_add_out.awk ${Exe_Output}_tail.txt )
1162      RET=$?
1163      if [ $RET -eq 0 ] ; then
1164        # ExeCpuLog variable contents 5 fields
1165        echo "${CumulPeriod} ${PeriodDateBegin} ${PeriodDateEnd} ${ExeCpuLog} ${ExeDate}" |   \
1166          gawk '{printf("# %11d | %15s | %15s | %19s | %19s | %15.5f | %15.5f | %15.5f | %s\n", \
1167            $1,$2,$3,$4,$5,$6,$7,$8,$9)}' >> ${SUBMIT_DIR}/run.card
1168      fi
1169      FileToBeDeleted[${#FileToBeDeleted[@]}]=${Exe_Output}_tail.txt
1170    fi
1171
1172  fi
1173
1174  #==================================#
1175  #         Save Job output          #
1176  #==================================#
1177  if [ X${Pack} = Xtrue ] ; then
1178    IGCM_sys_PutBuffer_Out ${Exe_Output} ${R_BUF_KSH}/${PREFIX}_${Exe_Output}
1179  else
1180    IGCM_sys_Put_Out ${Exe_Output} ${R_OUT_KSH}/${PREFIX}_${Exe_Output}
1181  fi
1182  FileToBeDeleted[${#FileToBeDeleted[@]}]=${Exe_Output}
1183
1184  # All was right ? no ? then we stop.
1185  IGCM_debug_Verif_Exit
1186
1187  # If all was OK, we can delete all files not necessary for next Job
1188  echo
1189  IGCM_debug_Print 1 "Files that will be deleted before next period-run : "
1190
1191  if [ ${DRYRUN} -le 2 ] ; then
1192    for f in ${FileToBeDeleted[@]} ; do [ -f ${f} ] && ls -la $f ; [ -f ${f} ] && rm -f $f ; done
1193  else
1194    echo ${FileToBeDeleted[@]}
1195  fi
1196
1197  # Send some accounting element to the user if CumulPeriod=3
1198  if [ ${CumulPeriod} -eq 3 ] ; then
1199    echo
1200    IGCM_debug_Print 1 "Send email containing some accounting information : "
1201
1202    RealCpuTime=$( echo ${ExeCpuLog} | gawk '{print $3}' )
1203
1204    consumeHoursPerPeriod=$( echo "scale=6;${RealCpuTime}*${coreNumber}/3600" | bc )
1205
1206    consumeHoursPerWholeSimulation=$( echo "scale=6;${consumeHoursPerPeriod}/${PeriodLengthInDays}*${ExperienceLengthInDays}" | bc )
1207
1208    recommendedPeriodNb=$( echo "scale=6;${jobWarningDelay}/3600/${consumeHoursPerPeriod}*${coreNumber}" | bc )
1209
1210    IGCM_sys_SendMail Accounting
1211  fi
1212
1213  #=================================================#
1214  #         Modification of libIGCM behaviour       #
1215  #=================================================#
1216
1217  # To use this function, one must copy libIGCM.card from ${libIGCM} directory
1218  # and put it in ${SUBMIT_DIR} directory. After modifications of ${SUBMIT_DIR}/libIGCM.card,
1219  # variables define inside [UserChanges] will be modified for next Period of libIGCM main loop.
1220  if [ -f ${SUBMIT_DIR}/libIGCM.card ] ; then
1221    echo
1222    echo "########################################################################"
1223    echo "!!!                 Modification of libIGCM behaviour                !!!"
1224    echo
1225
1226    IGCM_debug_Print 1 "DefineArrayFromOption  : libIGCM_UserChanges in libIGCM.card"
1227    IGCM_card_DefineArrayFromSection ${SUBMIT_DIR}/libIGCM.card UserChanges
1228    IGCM_debug_Print 2 "libIGCM_UserChanges" ${libIGCM_UserChanges[*]}
1229
1230    # Special treatments for libIGCM internals
1231    for option in ${libIGCM_UserChanges[*]} ; do
1232      IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/libIGCM.card UserChanges ${option}
1233
1234      echo "We will change : ${option}."
1235      eval echo "Previous value : " \${${option}}
1236      eval echo "Change to : " \${libIGCM_UserChanges_${option}}
1237
1238      eval ${option}=\${libIGCM_UserChanges_${option}}
1239
1240      case ${option} in
1241      config_UserChoices_DateEnd)
1242        IGCM_debug_PrintVariables 1 config_UserChoices_DateEnd
1243        DateEnd=$( IGCM_date_ConvertFormatToGregorian ${config_UserChoices_DateEnd} )
1244
1245        # Period Length In Days between DateBegin and DateEnd
1246        (( ExperienceLengthInDays=$( IGCM_date_DaysBetweenGregorianDate ${DateEnd} ${DateBegin} )  + 1 ))
1247        if [ ${ExperienceLengthInDays} -lt 0 ] ; then
1248          IGCM_debug_Print 1 "Problem with dates in libIGCM.card : ${DateEnd} < ${DateBegin} ! You must check that."
1249          IGCM_debug_Exit "IGCM_PeriodEnd have wrong dates."
1250          IGCM_debug_Verif_Exit
1251        fi
1252        ;;
1253      config_UserChoices_PeriodLength)
1254        IGCM_debug_Print 1  "Change config_UserChoices_PeriodLength=${config_UserChoices_PeriodLength}"
1255        ;;
1256      PeriodNb)
1257        IGCM_debug_Print 1  "Loop in main Job with ${PeriodNb} period(s)"
1258        ;;
1259      config_Post_RebuildFrequency)
1260        IGCM_debug_Print 1  "Change config_Post_RebuildFrequency=${config_Post_RebuildFrequency} : IGCM_post_Configure"
1261        IGCM_post_Configure
1262        ;;
1263      config_Post_TimeSeriesFrequency)
1264        IGCM_debug_Print 1  "Change config_Post_TimeSeriesFrequency = ${config_Post_TimeSeriesFrequency} : IGCM_post_Configure"
1265        IGCM_post_Configure
1266        ;;
1267      config_Post_SeasonalFrequency)
1268        IGCM_debug_Print 1  "Change config_Post_SeasonalFrequency = ${config_Post_SeasonalFrequency} : IGCM_post_Configure"
1269        IGCM_post_Configure
1270        ;;
1271      esac
1272    done
1273
1274    echo
1275    echo "########################################################################"
1276    echo
1277  fi
1278
1279  #=================================================#
1280  #         Determine next computed period          #
1281  #=================================================#
1282
1283  PeriodDateBegin=$( IGCM_date_AddDaysToGregorianDate ${PeriodDateEnd} 1 )
1284  IGCM_date_GetYearMonthDay $PeriodDateBegin year month day
1285  year_m1=$(( year - 1 ))
1286  year_p1=$(( year + 1 ))
1287  IGCM_config_DaysInPeriodLength
1288  PeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate ${PeriodDateBegin} $(( ${PeriodLengthInDays} - 1 )) )
1289
1290  # Debug Print :
1291  echo
1292  IGCM_debug_Print 1 "IGCM_config_PeriodEnd : Preparing Next Execution"
1293  IGCM_debug_Print 1 "PeriodDateBegin       : ${PeriodDateBegin}"
1294  IGCM_debug_Print 1 "PeriodDateEnd         : ${PeriodDateEnd}"
1295  IGCM_debug_Print 1 "PeriodLengthInDays    : ${PeriodLengthInDays}"
1296
1297  PeriodDateBegin=$( IGCM_date_ConvertFormatToHuman ${PeriodDateBegin} )
1298  PeriodDateEnd=$( IGCM_date_ConvertFormatToHuman ${PeriodDateEnd} )
1299
1300  (( CumulPeriod = CumulPeriod + 1 ))
1301
1302  # Debug Print :
1303  echo
1304  IGCM_debug_Print 3 "PeriodDateBegin Human : ${PeriodDateBegin}"
1305  IGCM_debug_Print 3 "PeriodDateEnd Human   : ${PeriodDateEnd}"
1306  IGCM_debug_Print 3 "CumulPeriod           : ${CumulPeriod}"
1307
1308  #=================================================#
1309  #             Write updated run.card              #
1310  #=================================================#
1311
1312  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateBegin ${PeriodDateBegin}
1313  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateEnd ${PeriodDateEnd}
1314  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration CumulPeriod ${CumulPeriod}
1315
1316  if ( ${FirstInitialize} ) ; then
1317    # It's no more the first time
1318    FirstInitialize=false
1319  fi
1320
1321  IGCM_debug_PopStack "IGCM_config_PeriodEnd"
1322}
1323
1324#===================================
1325function IGCM_config_Finalize
1326{
1327  IGCM_debug_PushStack "IGCM_config_Finalize"
1328
1329  echo
1330  IGCM_debug_Print 1 "IGCM_config_Finalize"
1331  echo
1332
1333  # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
1334  IGCM_config_StateCheck
1335
1336  # And EXIT if not OK
1337  IGCM_debug_Verif_Exit
1338
1339  if [ ${SimulationLengthInDays} -ge ${ExperienceLengthInDays} ] ; then
1340    #==========================#
1341    # End of entire simulation #
1342    #==========================#
1343    simulationIsOver=true
1344
1345    # Mail notification
1346    IGCM_sys_SendMail
1347    #
1348    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Completed"
1349    #
1350    IGCM_debug_Print 1 "Normal End of computation."
1351
1352  else
1353    #=================#
1354    # Submit next job #
1355    #=================#
1356    simulationIsOver=false
1357
1358    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "OnQueue"
1359
1360    # Name of next Ksh Script output :
1361    Script_Output=${Script_Output_Prefix}_${config_UserChoices_JobName}.$( printf "%06d" ${CumulPeriod} )
1362
1363    IGCM_debug_Print 1 "Submit next job"
1364    # SUBMIT NEXT JOB from SUBMIT_DIR and come back in RUN_DIR
1365    IGCM_sys_Cd ${SUBMIT_DIR}
1366    # Keep only the 5 latest ${Script_Output_Prefix}_${config_UserChoices_JobName}
1367    ScriptTot=$( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.?????? 2>/dev/null | wc -l )
1368    [ ${ScriptTot} -gt 5 ] && rm -f $( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.?????? | head -$(( ${ScriptTot} - 5 )) )
1369    # Submit next job and come back
1370    IGCM_sys_Qsub ${SUBMIT_DIR}/Job_${config_UserChoices_JobName}
1371    IGCM_sys_Cd -
1372  fi
1373
1374  # Clean ${RUN_DIR}=${RUN_DIR_PATH}/${config_UserChoices_JobName}.${$}
1375  # Only for production run (No clean up in DEV or DEB mode)
1376  # and command sent from .. directory.
1377  IGCM_sys_Cd ..
1378  [ X${JobType} = XRUN ] && IGCM_sys_RmRunDir -rf ${RUN_DIR_PATH}
1379
1380  # Inform the rabbitMQ queue
1381  IGCM_debug_BigBro_Finalize
1382
1383  IGCM_debug_PopStack "IGCM_config_Finalize"
1384}
1385
1386#===================================
Note: See TracBrowser for help on using the repository browser.