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

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