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

Last change on this file since 1392 was 1392, checked in by sdipsl, 7 years ago
  • 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.1 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_PutBuffer_Out ${Potential} ${R_BUF_KSH}/${Potential}.$$ NOCHMOD
831        else
832          ( IGCM_sys_TestFileArchive ${R_OUT_KSH}/${Potential} ) || IGCM_sys_Put_Out ${Potential} ${R_OUT_KSH}/${Potential}.$$ NOCHMOD
833        fi
834      done
835      #
836      IGCM_debug_Print 2 "Save current run.card"
837      IGCM_card_CheckConflict run.card
838
839      if [ X${Pack} = Xtrue ] ; then
840        IGCM_sys_PutBuffer_Out ${SUBMIT_DIR}/run.card ${R_BUF_KSH}/${PREFIX}_${Exe_Output} NOCHMOD
841      else
842        IGCM_sys_Put_Out ${SUBMIT_DIR}/run.card ${R_OUT_KSH}/${PREFIX}_${Exe_Output} NOCHMOD
843      fi
844      #
845      IGCM_sys_Cd ${RUN_DIR}
846    else
847      unset FileToBeDeleted
848    fi
849
850    # Determine number of day(s) in PeriodLength
851    IGCM_date_GetYearMonthDay $PeriodDateBegin year month day
852    IGCM_config_DaysInPeriodLength
853
854    # Check coherency between (PeriodDateBegin, PeriodDateEnd) and (DateBegin, CumulPeriod, PeriodLength)
855    IGCM_config_DateCoherency
856    # And EXIT if not OK
857    IGCM_debug_Verif_Exit
858
859    # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
860    IGCM_config_StateCheck
861    # And EXIT if not OK
862    IGCM_debug_Verif_Exit
863
864    # We can say we are "Running" now.
865    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Running"
866  fi
867
868  # BEGIN: SHOULD GO IN A FUNCTION FROM libIGCM_date.ksh
869  # Compute year_m1 and year_p1 (year minus 1Y and year plus 1Y)
870  year_m1=$(( year - 1 ))
871  year_p1=$(( year + 1 ))
872  # Compute month_m1 (month minus 1M)
873  # Compute yyyymm_m1 (yyyymm minus 1M)
874  month_m1=$(( 10#${month} - 1 ))
875  if [ ${month_m1} = 0 ]; then
876    month_m1=12
877    yyyymm_m1=${year_m1}12
878  elif [ ${month_m1} -le 9 ]; then
879    month_m1=0${month_m1}
880    yyyymm_m1=${year}${month_m1}
881  else
882    yyyymm_m1=${year}${month_m1}
883  fi
884  # Compute month_p1 (month plus 1M)
885  # Compute yyyymm_p1 (yyyymm plus 1M)
886  month_p1=$(( 10#${month} + 1 ))
887  if [ ${month_p1} = 13 ]; then
888    month_p1=01
889    yyyymm_p1=${year_p1}01
890  elif [ ${month_p1} -le 9 ]; then
891    month_p1=0${month_p1}
892    yyyymm_p1=${year}${month_p1}
893  else
894    yyyymm_p1=${year}${month_p1}
895  fi
896
897  #===================================================================#
898  # Calculate CyclicYear to be used for looping over a given forcing  #
899  # period. Add CyclicBegin and CyclicEnd in config.card UserChoices. #
900  #===================================================================#
901
902  # To use the variable CyclicYear, one must add in config.card CyclicBegin and CyclicEnd.
903  # CyclicBegin is the first year in the cycle. CyclicEnd is the last year included in the cycle.
904  if ( [ ! X${config_UserChoices_CyclicBegin} = X ] && [ ! X${config_UserChoices_CyclicEnd} = X ] ) ; then
905    CycleNb=$(( ${config_UserChoices_CyclicEnd} - ${config_UserChoices_CyclicBegin} + 1 ))
906    CyclicYear_p1=NOTDEFINED
907
908    # For current year
909    yeartmp=$year
910    diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
911    while [ $diffy -lt 0 ] ; do
912      yeartmp=$(( ${yeartmp} + ${CycleNb} ))
913      diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
914    done
915    CyclicYear=$(( ( ${diffy} % ${CycleNb} ) + ${config_UserChoices_CyclicBegin} ))
916
917    # For next coming year
918    yeartmp=$(( $year + 1 ))
919    diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
920    while [ $diffy -lt 0 ] ; do
921      yeartmp=$(( ${yeartmp} + ${CycleNb} ))
922      diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
923    done
924    CyclicYear_p1=$(( ( ${diffy} % ${CycleNb} ) + ${config_UserChoices_CyclicBegin} ))
925
926    IGCM_debug_Print 1 "CyclicYear   = ${CyclicYear}, CyclicYear_p1 = ${CyclicYear_p1}, current year=$year"
927  else
928    CyclicYear="ERROR_CyclicYear_Variable_Not_Defined"
929    CyclicYear_p1="ERROR_CyclicYear_p1_Variable_Not_Defined"
930    IGCM_debug_Print 1 "CyclicYear wont be use without adding CyclicBegin and CyclicEnd in config.card"
931  fi
932
933  # END: SHOULD GO IN A FUNCTION FROM libIGCM_date.ksh
934
935  #===================================================================#
936  # Prepare variables available for ${COMP}.card and ${COMP}.driver   #
937  #             But available to any son functions                    #
938  #===================================================================#
939
940  # Period Length In Days between DateBegin and DateCurrent (at end of period == PeriodDateEnd !)
941  (( SimulationLengthInDays = $( IGCM_date_DaysBetweenGregorianDate ${PeriodDateEnd} ${DateBegin} ) + 1 ))
942
943  # Debug Print :
944  echo
945  IGCM_debug_Print 1 "IGCM_config_PeriodStart : Before Execution"
946  IGCM_debug_Print 1 "Year of simulation      : ${year}"
947  IGCM_debug_Print 1 "Month of simulation     : ${month}"
948  IGCM_debug_Print 1 "PeriodLengthInDays      : ${PeriodLengthInDays}"
949  IGCM_debug_Print 1 "PeriodDateBegin         : ${PeriodDateBegin}"
950  IGCM_debug_Print 1 "PeriodDateEnd           : ${PeriodDateEnd}"
951  IGCM_debug_Print 1 "SimulationLengthInDays  : ${SimulationLengthInDays}"
952  IGCM_debug_Print 1 "ExperienceLengthInDays  : ${ExperienceLengthInDays}"
953
954  #================================================================#
955  #         Prepare variables available for comp_finalyze          #
956  #================================================================#
957
958  # Period for save files
959  DatesPeriod=${PeriodDateBegin}_${PeriodDateEnd}
960
961  # Prefix for save files of this period
962  PREFIX=${config_UserChoices_JobName}_${DatesPeriod}
963
964  # List of files that will be deleted in RUN_DIR after run
965  [ -f stack ] && FileToBeDeleted[0]="stack"
966
967  # Test if the same run as already been saved :
968  if [ X${JobType} = XRUN ] ; then
969    if [ ${DRYRUN} -le 0 ] ; then
970      if ( IGCM_sys_TestFileBuffer ${R_BUF_KSH}/${PREFIX}_${Exe_Output} ) ; then
971        IGCM_debug_Exit "IGCM_config_PeriodStart" "You are currently re-running an old job."
972        IGCM_debug_Print 1 "Because of readonly permissions, you can't re-run a job when saved files"
973        IGCM_debug_Print 1 " are still in the ARCHIVE directory. You must deleted those files, or "
974        IGCM_debug_Print 1 " the whole ${R_SAVE} tree. See different clean_*.job in ${libIGCM} directory."
975        IGCM_debug_Print 1 " This exit has been initiated because at least ${R_BUF_KSH}/${PREFIX}_${Exe_Output} exists."
976        IGCM_debug_Verif_Exit
977      fi
978    fi
979  else
980    if ( IGCM_sys_TestFileBuffer ${R_BUF_KSH}/${PREFIX}_${Exe_Output} ) ; then
981      IGCM_debug_Print 1 "IGCM_config_PeriodStart" "RErun an old job. Allowed in DEBUG or DEV mode."
982    fi
983  fi
984
985  #================================================================#
986  #       Prepare variables available for binary execution         #
987  #       Call function for creation of run script                 #
988  #       Only done once per job                                   #
989  #================================================================#
990
991  if [ ${Period} -eq 1 ]; then
992    # Define the execution context (MPMD, SPMD, MPI/OMP ...)
993    IGCM_config_ConfigureExecution ${SUBMIT_DIR}/config.card
994    # Create the execution script for the current context
995    IGCM_sys_build_execution_scripts
996  fi
997
998  ExecutionFail=false
999
1000  # Update the rabbitMQ queue
1001  IGCM_debug_BigBro_Update
1002
1003  IGCM_debug_PopStack "IGCM_config_PeriodStart"
1004}
1005
1006#===================================
1007function IGCM_config_SaveSourceModifications
1008{
1009  IGCM_debug_PushStack "IGCM_config_SaveSourceModifications"
1010
1011  typeset ExeOutDateMax listVarEnv
1012  ExeOutDateMax=$1
1013
1014  listVarEnv="ExeOutDateMax,R_OUT_EXE,PREFIX,SUBMIT_DIR"
1015  IGCM_sys_RshMaster "\
1016    . ${libIGCM}/libIGCM_sys/libIGCM_sys.ksh; \
1017    export ExeOutDateMax=${ExeOutDateMax};\
1018    export R_OUT_EXE=${R_OUT_EXE};\
1019    export PREFIX=${PREFIX};\
1020    export SUBMIT_DIR=${SUBMIT_DIR};\
1021    export listVarEnv=${listVarEnv};\
1022    Script_Output=out_SaveSourceModifications;\
1023    IGCM_sys_Qsub ${libIGCM}/SaveSourceModifications.job ${ExeOutDateMax} ${R_OUT_EXE} ${PREFIX} ${SUBMIT_DIR}"
1024
1025  IGCM_debug_PopStack "IGCM_config_SaveSourceModifications"
1026}
1027
1028#===================================
1029function IGCM_config_PeriodEnd
1030{
1031  IGCM_debug_PushStack "IGCM_config_PeriodEnd"
1032
1033  echo
1034  IGCM_debug_Print 1 "IGCM_config_PeriodEnd"
1035  echo
1036
1037  if [ ${DRYRUN} -le 1 ] ; then
1038
1039    IGCM_debug_Print 1 "Check components binary : size and creation date"
1040
1041    typeset LS_comp LS_bin ExeDate ExeCpuLog NextExeSize LastCompExeSize
1042    typeset comp i
1043    typeset ExeNameIn ExeNameOut UpdateExe ExeSecDateMax
1044
1045    #==================================#
1046    #        Get last Exe Size         #
1047    #==================================#
1048
1049    (( i=0 ))
1050    if ( ${FirstInitialize} ) ; then
1051      run_Log_LastExeSize=""
1052      for comp in ${config_ListOfComponents[*]} ; do
1053        run_Log_LastExeSize[$i]=0
1054        (( i=i+1 ))
1055      done
1056    else
1057      IGCM_card_DefineArrayFromOption ${SUBMIT_DIR}/run.card Log LastExeSize
1058    fi
1059    #==================================#
1060    #         And Build ExeDate        #
1061    #==================================#
1062
1063    # 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
1064    # 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")
1065    # 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
1066    ExeDate=""
1067    NextExeSize="( "
1068    (( i=0 ))
1069    UpdateExe=false
1070    (( ExeSecDateMax = 0 ))
1071    for comp in ${config_ListOfComponents[*]} ; do
1072
1073      IGCM_debug_Print 3 ${comp}
1074
1075      eval ExeNameIn=\${config_Executable_${comp}[0]}
1076      eval ExeNameOut=\${config_Executable_${comp}[1]}
1077      # Only if we really have an executable for the component :
1078      if [ X${ExeNameIn} = X\"\" ] ; then
1079        # If there is no exe file for this component
1080        (( ExeSize=0 ))
1081      else
1082        LS_bin=${R_EXE}/${ExeNameIn}
1083        IGCM_sys_FileSize ${LS_bin} ExeSize
1084
1085        set +A LS_comp -- $( LC_TIME=en_US ls -l ${LS_bin} )
1086        if [ X${ExeDate} = X ] ; then
1087          # First component exe date
1088          ExeDate=${comp}_${LS_comp[5]}_${LS_comp[6]}
1089        else
1090          ExeDate=${ExeDate}-${comp}_${LS_comp[5]}_${LS_comp[6]}
1091        fi
1092        ExeDate=${ExeDate}_${LS_comp[7]}
1093      fi
1094
1095      if [ ${i} -eq 0 ] ; then
1096        # First component
1097        NextExeSize="( "${ExeSize}
1098      else
1099        NextExeSize=${NextExeSize}", "${ExeSize}
1100      fi
1101      LastCompExeSize=${run_Log_LastExeSize[$i]}
1102      (( i=i+1 ))
1103
1104      if [ ${ExeSize} -ne ${LastCompExeSize} ] ; then
1105        if ( ${FirstInitialize} ) ; then
1106          IGCM_debug_Print 1 "Save first ${ExeNameIn} in ${R_OUT_EXE} !"
1107        else
1108          IGCM_debug_Print 1 "${ExeNameIn} has changed in ${R_EXE} !"
1109          IGCM_debug_Print 1 "Save latest ${ExeNameIn} in ${R_OUT_EXE} !"
1110          FileToBeDeleted[${#FileToBeDeleted[@]}]=${ExeNameOut}
1111        fi
1112        IGCM_sys_Put_Out ${ExeNameOut} ${R_OUT_EXE}/${PREFIX}_${ExeNameIn} rw
1113        UpdateExe=true
1114
1115        # SD : switch off for now
1116        #IGCM_sys_GetDate_FichWork ${LS_bin} ExeSecDate
1117        #if [ $ExeSecDateMax -lt $ExeSecDate ] ; then
1118        #  ExeSecDateMax=$ExeSecDate
1119        #fi
1120      fi
1121    done
1122
1123    # SD : switch off for now
1124    #if ( ${UpdateExe} ) ; then
1125    #  echo "Launch SaveSourceModifications."
1126    #  IGCM_config_SaveSourceModifications ${ExeSecDateMax}
1127    #fi
1128
1129    NextExeSize=${NextExeSize}" )"
1130    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Log LastExeSize "${NextExeSize}"
1131
1132    if [ ${DRYRUN} -le 1 ] ; then
1133      tail -1500 ${Exe_Output} > ${Exe_Output}_tail.txt
1134      ExeCpuLog=$( gawk -f ${libIGCM}/libIGCM_sys/IGCM_add_out.awk ${Exe_Output}_tail.txt )
1135      RET=$?
1136      if [ $RET -eq 0 ] ; then
1137        # ExeCpuLog variable contents 5 fields
1138        echo "${CumulPeriod} ${PeriodDateBegin} ${PeriodDateEnd} ${ExeCpuLog} ${ExeDate}" |   \
1139          gawk '{printf("# %11d | %15s | %15s | %19s | %19s | %15.5f | %15.5f | %15.5f | %s\n", \
1140            $1,$2,$3,$4,$5,$6,$7,$8,$9)}' >> ${SUBMIT_DIR}/run.card
1141      fi
1142      FileToBeDeleted[${#FileToBeDeleted[@]}]=${Exe_Output}_tail.txt
1143    fi
1144
1145  fi
1146
1147  #==================================#
1148  #         Save Job output          #
1149  #==================================#
1150  if [ X${Pack} = Xtrue ] ; then
1151    IGCM_sys_PutBuffer_Out ${Exe_Output} ${R_BUF_KSH}/${PREFIX}_${Exe_Output}
1152  else
1153    IGCM_sys_Put_Out ${Exe_Output} ${R_OUT_KSH}/${PREFIX}_${Exe_Output}
1154  fi
1155  FileToBeDeleted[${#FileToBeDeleted[@]}]=${Exe_Output}
1156
1157  # All was right ? no ? then we stop.
1158  IGCM_debug_Verif_Exit
1159
1160  # If all was OK, we can delete all files not necessary for next Job
1161  echo
1162  IGCM_debug_Print 1 "Files that will be deleted before next period-run : "
1163
1164  if [ ${DRYRUN} -le 2 ] ; then
1165    for f in ${FileToBeDeleted[@]} ; do [ -f ${f} ] && ls -la $f ; [ -f ${f} ] && rm -f $f ; done
1166  else
1167    echo ${FileToBeDeleted[@]}
1168  fi
1169
1170  # Send some accounting element to the user if CumulPeriod=3
1171  if [ ${CumulPeriod} -eq 3 ] ; then
1172    echo
1173    IGCM_debug_Print 1 "Send email containing some accounting information : "
1174
1175    RealCpuTime=$( echo ${ExeCpuLog} | gawk '{print $3}' )
1176
1177    consumeHoursPerPeriod=$( echo "scale=6;${RealCpuTime}*${coreNumber}/3600" | bc )
1178
1179    consumeHoursPerWholeSimulation=$( echo "scale=6;${consumeHoursPerPeriod}/${PeriodLengthInDays}*${ExperienceLengthInDays}" | bc )
1180
1181    recommendedPeriodNb=$( echo "scale=6;${jobWarningDelay}/3600/${consumeHoursPerPeriod}*${coreNumber}" | bc )
1182
1183    IGCM_sys_SendMail Accounting
1184  fi
1185
1186  #=================================================#
1187  #         Modification of libIGCM behaviour       #
1188  #=================================================#
1189
1190  # To use this function, one must copy libIGCM.card from ${libIGCM} directory
1191  # and put it in ${SUBMIT_DIR} directory. After modifications of ${SUBMIT_DIR}/libIGCM.card,
1192  # variables define inside [UserChanges] will be modified for next Period of libIGCM main loop.
1193  if [ -f ${SUBMIT_DIR}/libIGCM.card ] ; then
1194    echo
1195    echo "########################################################################"
1196    echo "!!!                 Modification of libIGCM behaviour                !!!"
1197    echo
1198
1199    IGCM_debug_Print 1 "DefineArrayFromOption  : libIGCM_UserChanges in libIGCM.card"
1200    IGCM_card_DefineArrayFromSection ${SUBMIT_DIR}/libIGCM.card UserChanges
1201    IGCM_debug_Print 2 "libIGCM_UserChanges" ${libIGCM_UserChanges[*]}
1202
1203    # Special treatments for libIGCM internals
1204    for option in ${libIGCM_UserChanges[*]} ; do
1205      IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/libIGCM.card UserChanges ${option}
1206
1207      echo "We will change : ${option}."
1208      eval echo "Previous value : " \${${option}}
1209      eval echo "Change to : " \${libIGCM_UserChanges_${option}}
1210
1211      eval ${option}=\${libIGCM_UserChanges_${option}}
1212
1213      case ${option} in
1214      config_UserChoices_DateEnd)
1215        IGCM_debug_PrintVariables 1 config_UserChoices_DateEnd
1216        DateEnd=$( IGCM_date_ConvertFormatToGregorian ${config_UserChoices_DateEnd} )
1217
1218        # Period Length In Days between DateBegin and DateEnd
1219        (( ExperienceLengthInDays=$( IGCM_date_DaysBetweenGregorianDate ${DateEnd} ${DateBegin} )  + 1 ))
1220        if [ ${ExperienceLengthInDays} -lt 0 ] ; then
1221          IGCM_debug_Print 1 "Problem with dates in libIGCM.card : ${DateEnd} < ${DateBegin} ! You must check that."
1222          IGCM_debug_Exit "IGCM_PeriodEnd have wrong dates."
1223          IGCM_debug_Verif_Exit
1224        fi
1225        ;;
1226      config_UserChoices_PeriodLength)
1227        IGCM_debug_Print 1  "Change config_UserChoices_PeriodLength=${config_UserChoices_PeriodLength}"
1228        ;;
1229      PeriodNb)
1230        IGCM_debug_Print 1  "Loop in main Job with ${PeriodNb} period(s)"
1231        ;;
1232      config_Post_RebuildFrequency)
1233        IGCM_debug_Print 1  "Change config_Post_RebuildFrequency=${config_Post_RebuildFrequency} : IGCM_post_Configure"
1234        IGCM_post_Configure
1235        ;;
1236      config_Post_TimeSeriesFrequency)
1237        IGCM_debug_Print 1  "Change config_Post_TimeSeriesFrequency = ${config_Post_TimeSeriesFrequency} : IGCM_post_Configure"
1238        IGCM_post_Configure
1239        ;;
1240      config_Post_SeasonalFrequency)
1241        IGCM_debug_Print 1  "Change config_Post_SeasonalFrequency = ${config_Post_SeasonalFrequency} : IGCM_post_Configure"
1242        IGCM_post_Configure
1243        ;;
1244      esac
1245    done
1246
1247    echo
1248    echo "########################################################################"
1249    echo
1250  fi
1251
1252  #=================================================#
1253  #         Determine next computed period          #
1254  #=================================================#
1255
1256  PeriodDateBegin=$( IGCM_date_AddDaysToGregorianDate ${PeriodDateEnd} 1 )
1257  IGCM_date_GetYearMonthDay $PeriodDateBegin year month day
1258  year_m1=$(( year - 1 ))
1259  year_p1=$(( year + 1 ))
1260  IGCM_config_DaysInPeriodLength
1261  PeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate ${PeriodDateBegin} $(( ${PeriodLengthInDays} - 1 )) )
1262
1263  # Debug Print :
1264  echo
1265  IGCM_debug_Print 1 "IGCM_config_PeriodEnd : Preparing Next Execution"
1266  IGCM_debug_Print 1 "PeriodDateBegin       : ${PeriodDateBegin}"
1267  IGCM_debug_Print 1 "PeriodDateEnd         : ${PeriodDateEnd}"
1268  IGCM_debug_Print 1 "PeriodLengthInDays    : ${PeriodLengthInDays}"
1269
1270  PeriodDateBegin=$( IGCM_date_ConvertFormatToHuman ${PeriodDateBegin} )
1271  PeriodDateEnd=$( IGCM_date_ConvertFormatToHuman ${PeriodDateEnd} )
1272
1273  (( CumulPeriod = CumulPeriod + 1 ))
1274
1275  # Debug Print :
1276  echo
1277  IGCM_debug_Print 3 "PeriodDateBegin Human : ${PeriodDateBegin}"
1278  IGCM_debug_Print 3 "PeriodDateEnd Human   : ${PeriodDateEnd}"
1279  IGCM_debug_Print 3 "CumulPeriod           : ${CumulPeriod}"
1280
1281  #=================================================#
1282  #             Write updated run.card              #
1283  #=================================================#
1284
1285  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateBegin ${PeriodDateBegin}
1286  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateEnd ${PeriodDateEnd}
1287  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration CumulPeriod ${CumulPeriod}
1288
1289  if ( ${FirstInitialize} ) ; then
1290    # It's no more the first time
1291    FirstInitialize=false
1292  fi
1293
1294  IGCM_debug_PopStack "IGCM_config_PeriodEnd"
1295}
1296
1297#===================================
1298function IGCM_config_Finalize
1299{
1300  IGCM_debug_PushStack "IGCM_config_Finalize"
1301
1302  echo
1303  IGCM_debug_Print 1 "IGCM_config_Finalize"
1304  echo
1305
1306  # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
1307  IGCM_config_StateCheck
1308
1309  # And EXIT if not OK
1310  IGCM_debug_Verif_Exit
1311
1312  if [ ${SimulationLengthInDays} -ge ${ExperienceLengthInDays} ] ; then
1313    #==========================#
1314    # End of entire simulation #
1315    #==========================#
1316    simulationIsOver=true
1317
1318    # Mail notification
1319    IGCM_sys_SendMail
1320    #
1321    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Completed"
1322    #
1323    IGCM_debug_Print 1 "Normal End of computation."
1324
1325  else
1326    #=================#
1327    # Submit next job #
1328    #=================#
1329    simulationIsOver=false
1330
1331    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "OnQueue"
1332
1333    # Name of next Ksh Script output :
1334    Script_Output=${Script_Output_Prefix}_${config_UserChoices_JobName}.$( printf "%06d" ${CumulPeriod} )
1335
1336    IGCM_debug_Print 1 "Submit next job"
1337    # SUBMIT NEXT JOB from SUBMIT_DIR and come back in RUN_DIR
1338    IGCM_sys_Cd ${SUBMIT_DIR}
1339    # Keep only the 5 latest ${Script_Output_Prefix}_${config_UserChoices_JobName}
1340    ScriptTot=$( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.?????? 2>/dev/null | wc -l )
1341    [ ${ScriptTot} -gt 5 ] && rm -f $( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.?????? | head -$(( ${ScriptTot} - 5 )) )
1342    # Submit next job and come back
1343    IGCM_sys_Qsub ${SUBMIT_DIR}/Job_${config_UserChoices_JobName}
1344    IGCM_sys_Cd -
1345  fi
1346
1347  # Clean ${RUN_DIR}=${RUN_DIR_PATH}/${config_UserChoices_JobName}.${$}
1348  # Only for production run (No clean up in DEV or DEB mode)
1349  # and command sent from .. directory.
1350  IGCM_sys_Cd ..
1351  [ X${JobType} = XRUN ] && IGCM_sys_RmRunDir -rf ${RUN_DIR_PATH}
1352
1353  # Inform the rabbitMQ queue
1354  IGCM_debug_BigBro_Finalize
1355
1356  IGCM_debug_PopStack "IGCM_config_Finalize"
1357}
1358
1359#===================================
Note: See TracBrowser for help on using the repository browser.