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

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