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

Last change on this file since 1250 was 1250, checked in by sdipsl, 9 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: 51.2 KB
Line 
1#!/bin/ksh
2
3#**************************************************************
4# Author: Sebastien Denvil, Martial Mancip
5# Contact: Sebastien.Denvil__at__ipsl.jussieu.fr Martial.Mancip__at__ipsl.jussieu.fr
6# $Revision::                                          $ Revision of last commit
7# $Author::                                            $ Author of last commit
8# $Date::                                              $ Date of last commit
9# IPSL (2006)
10#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
11#
12#**************************************************************
13
14#===================================
15function IGCM_config_CommonConfiguration
16{
17  IGCM_debug_PushStack "IGCM_config_CommonConfiguration" $@
18
19  # Debug Print :
20  [ ${Verbosity} -gt 0 ] && echo
21  IGCM_debug_Print 1 "IGCM_config_CommonConfiguration" $@
22
23  # config.card path
24  configCardPath=$1
25
26  #==================================
27  typeset option auxprint
28
29  #==================================
30  # Read UserChoices section:
31  [ ${Verbosity} -gt 0 ] && echo
32  IGCM_debug_Print 1 "DefineArrayFromOption  : config_UserChoices"
33
34  IGCM_card_DefineArrayFromSection ${configCardPath} UserChoices
35  for option in ${config_UserChoices[*]} ; do
36    IGCM_card_DefineVariableFromOption ${configCardPath} UserChoices ${option}
37    eval auxprint=\${config_UserChoices_${option}}
38    IGCM_debug_Print 3 "${option} : ${auxprint}"
39  done
40
41  #==================================
42  # Read Ensemble section:
43  [ ${Verbosity} -gt 0 ] && echo
44  IGCM_debug_Print 1 "DefineArrayFromOption  : config_Ensemble"
45
46  IGCM_card_DefineArrayFromSection ${configCardPath} Ensemble
47  for option in ${config_Ensemble[*]} ; do
48    IGCM_card_DefineVariableFromOption ${configCardPath} Ensemble ${option}
49    eval auxprint=\${config_Ensemble_${option}}
50    IGCM_debug_Print 3 "${option} : ${auxprint}"
51  done
52
53  #==================================
54  # Read Post section:
55  [ ${Verbosity} -gt 0 ] && echo
56  IGCM_debug_Print 1 "DefineArrayFromOption : config_Post"
57
58  IGCM_card_DefineArrayFromSection ${configCardPath} Post
59  for option in ${config_Post[*]} ; do
60    IGCM_card_DefineVariableFromOption ${configCardPath} Post ${option}
61    eval auxprint=\${config_Post_${option}}
62    IGCM_debug_Print 3 "${option} : ${auxprint}"
63  done
64  [ ${Verbosity} -gt 0 ] && echo
65
66  #==================================
67  # Define default value to keep compatibility with previous card: means before changes due to TGCC
68  # Apply some overrules to ensure proper usage of computing centres resources
69  #
70  if [ X${PackDefault} = Xtrue ] ; then
71    if [ X${config_UserChoices_SpaceName} = XTEST ]; then
72      # TEST simulations will not be packed and will stay on SCRATCHDIR filesystem
73      IGCM_debug_Print 1 "SpaceName=TEST. OVERRULE PackFrequency to NONE"
74      config_Post_PackFrequency=NONE
75    else
76      # Default to RebuildFrequency if nothing has been set up related to PackFrequency
77      [ X${config_Post_PackFrequency} = X ] && config_Post_PackFrequency=${config_Post_RebuildFrequency}
78    fi
79  else
80    # If we DO NOT apply pack in this computing center
81    config_Post_PackFrequency=NONE
82  fi
83
84  #====================================================
85  # Define ARCHIVE : Dedicated to large files
86  # Define STORAGE : Dedicated to small/medium files
87  # Define R_OUT   : Output tree located on ARCHIVE
88  # Define R_BUF   : Output tree located on STORAGE (files waiting treatment, or file lcoation when SpaceName=!PROD)
89  # Define R_FIG   : Output tree located on STORAGE hosting figures (monitoring and atlas, and/or small files)
90  # Define R_TMP   : A temporary space used by IGCM_debug_send_AMQP_msg__MAILTUNNEL. Must be persistent in between jobs
91  IGCM_sys_defineArchives
92
93  #====================================================
94  # R_SAVE : Job output directory
95  # R_BUFR : Job output buffered directory
96
97  if ( [ ! X${config_UserChoices_SpaceName} = X ] && [ ! X${config_UserChoices_ExperimentName} = X ] ) ; then
98    FreeName=$( echo ${config_UserChoices_JobName} | sed 's/.*_//' )
99    if ( [ ! X${config_Ensemble_EnsembleName} = X ] && [ ! X${config_Ensemble_EnsembleDate} = X ] ) ; then
100      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
101      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
102      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
103      R_DODS=${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${FreeName}
104    else
105      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
106      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
107      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
108      R_DODS=${config_UserChoices_TagName}/${config_UserChoices_SpaceName}/${config_UserChoices_ExperimentName}/${FreeName}
109    fi
110  else
111    if ( [ ! X${config_Ensemble_EnsembleName} = X ] && [ ! X${config_Ensemble_EnsembleDate} = X ] ) ; then
112      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
113      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
114      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
115      R_DODS=${config_UserChoices_TagName}/${config_Ensemble_EnsembleName}/${config_Ensemble_EnsembleDate}/${config_UserChoices_JobName}
116    else
117      R_SAVE=${R_OUT}/${config_UserChoices_TagName}/${config_UserChoices_JobName}
118      R_FIGR=${R_FIG}/${config_UserChoices_TagName}/${config_UserChoices_JobName}
119      R_BUFR=${R_BUF}/${config_UserChoices_TagName}/${config_UserChoices_JobName}
120      R_DODS=${config_UserChoices_TagName}/${config_UserChoices_JobName}
121    fi
122  fi
123
124  #====================================================
125  # Define R_OUT_KSH : Storage place for job output
126  # Define R_OUT_EXE : Storage place for binary used during simulation
127  R_OUT_KSH=${R_SAVE}/Out
128  R_OUT_EXE=${R_SAVE}/Exe
129
130  #====================================================
131  # Define R_BUF_KSH : Buffer place for job output
132  # Define R_BUF_EXE : Buffer place for binary used during simulation
133  R_BUF_KSH=${R_BUFR}/Out
134  R_BUF_EXE=${R_BUFR}/Exe
135
136  #====================================================
137  # Define REBUILD_DIR : where we store files needing rebuild process
138  REBUILD_DIR=${R_BUFR}/REBUILD
139  if [ ! X${TaskType} = Xchecking ] ; then
140    IGCM_sys_MkdirWork ${REBUILD_DIR}
141  fi
142
143  #====================================================
144  # DodsCopy : apply default value if not defined
145  if ( [ X${config_Post_DodsCopy} = X${NULL_STR} ] || [ X${config_Post_DodsCopy} = X ] ) ; then
146    config_Post_DodsCopy=TRUE
147  fi
148
149  #====================================================
150  # 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    # Manage component executable
591    IGCM_card_DefineArrayFromOption ${configCardPath} Executable ${comp}
592
593    eval ExeNameIn=\${config_Executable_${comp}[0]}
594
595    # NO order in config.card for parallelized values !
596    # just use suffix : MPI , OMP and NOD (for number of NODes.)
597
598    # NOD is the number of NODes allocated
599    eval ${comp}_PROC_NOD=0
600
601    # MPI is the number of MPI processus per nodes
602    eval ${comp}_PROC_MPI=0
603
604    # OMP is the number of OpenMP threads per MPI processus
605    eval ${comp}_PROC_OMP=0
606
607    # Only if we really have an executable for the component :
608    if ( [ "X${ExeNameIn}" != X\"\" ] && [ "X${ExeNameIn}" != "Xinca.dat" ] ) ; then
609
610      IGCM_debug_Print 1 ${comp}
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 NOT SUPPORTED ANYMORE
662        #
663        IGCM_debug_Print 2 "You are using a deprecated ressources specification mechanism in your config.card"
664        IGCM_debug_Print 2 "Please check : https://forge.ipsl.jussieu.fr/igcmg_doc/wiki/DocEsetup#ThesectionExecutable"
665        IGCM_debug_Exit "Please modify your config card accoprdingly"
666        IGCM_debug_Verif_Exit
667      fi
668      eval tempvarMPI=\${${comp}_PROC_MPI}
669      eval tempvarNOD=\${${comp}_PROC_NOD}
670      eval tempvarOMP=\${${comp}_PROC_OMP}
671
672      # set OMP mode if more than 1 OMP thread.
673      [ ${tempvarOMP} -ge 2 ] && OK_PARA_OMP=true
674
675      # Number of OMP threads
676      [ ${openMPthreads} -lt ${tempvarOMP} ] && openMPthreads=${tempvarOMP}
677
678      # SUM UP NUMBER OF CORES
679      (( coreNumber = coreNumber + tempvarMPI * tempvarNOD * tempvarOMP ))
680
681      # SUM UP NUMBER OF MPI TASKS
682      (( mpiTasks = mpiTasks + tempvarMPI * tempvarNOD ))
683    fi
684  done
685
686  # MANDATORY FOR THE OPA9.DRIVER. USED TO EDIT OPA NAMELIST
687  # WE SHOULD PLANIFY NUM_PROC_??? DEPRECATION
688  NUM_PROC_CPL=${CPL_PROC_MPI}
689  NUM_PROC_OCE=${OCE_PROC_MPI}
690  NUM_PROC_ATM=${ATM_PROC_MPI}
691
692  # set MPMD mode if more than 2 executable names.
693  [ ${NbExec} -ge 2 ] && OK_PARA_MPMD=true 
694
695  # Define the execution type we are running in
696  if [ ${OK_PARA_MPMD} ] ; then
697    if [ ${OK_PARA_MPI} ] ; then
698      # MPMD always implies MPI
699      executionType=1
700    fi
701    if [ ${OK_PARA_OMP} ] ; then
702      # MPMD + MPI/OMP
703      executionType=2
704    fi
705  else
706    if ( [ ${OK_PARA_MPI} ] && [ ${OK_PARA_OMP} ] ) ; then
707      # SPMD + MPI/OMP
708      executionType=3
709    elif ( [ ${OK_PARA_MPI} ] && [ ! ${OK_PARA_OMP} ] ) ; then
710      # SPMD + MPI only
711      executionType=4
712    elif ( [ ! ${OK_PARA_MPI} ] && [ ${OK_PARA_OMP} ] ) ; then
713      # SPMD + OMP only
714      executionType=5
715    elif ( [ ! ${OK_PARA_MPI} ] && [ ! ${OK_PARA_OMP} ] ) ; then
716      # SEQUENTIAL THEN
717      executionType=6
718      coreNumber=1
719    fi
720  fi
721
722  IGCM_debug_Print 1 "MPI/OMP treatment coreNumber = ${coreNumber}"
723  IGCM_debug_Print 1 "MPI/OMP treatment mpiTasks = ${mpiTasks}"
724  IGCM_debug_Print 1 "MPI/OMP treatment openMPthreads = ${openMPthreads}"
725  IGCM_debug_Print 1 "MPI/OMP treatment executionType = ${executionType}"
726
727  IGCM_debug_PopStack "IGCM_config_ConfigureExecution"
728}
729
730#===================================
731function IGCM_config_PeriodStart
732{
733  IGCM_debug_PushStack "IGCM_config_PeriodStart"
734
735  echo
736  IGCM_debug_Print 1 "IGCM_config_PeriodStart"
737  echo
738
739  if ( ${FirstInitialize} ) ; then
740    #================================================#
741    #         Initialize date/period information     #
742    #================================================#
743
744    IGCM_date_GetYearMonthDay ${DateBegin} year month day
745    IGCM_config_DaysInPeriodLength
746
747    PeriodDateBegin=${DateBegin}
748    PeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate ${DateBegin} $(( ${PeriodLengthInDays} - 1 )) )
749    CumulPeriod=1
750
751    #=================================================#
752    #              Write updated run.card             #
753    #=================================================#
754
755    #Correct run.card Configuration for this period
756    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateBegin ${PeriodDateBegin}
757    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateEnd ${PeriodDateEnd}
758    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration CumulPeriod ${CumulPeriod}
759    if [ X$( grep "SubmitPath" ${SUBMIT_DIR}/run.card ) != X ] ; then
760      IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration SubmitPath ${SUBMIT_DIR}
761    fi
762
763    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Running"
764
765  else
766    #================================================#
767    #         The file run.card allready exist       #
768    #================================================#
769
770    # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
771    IGCM_config_StateCheck
772    # And EXIT if not OK
773    IGCM_debug_Verif_Exit
774
775    #===================================#
776    #        Read updated run.card      #
777    #===================================#
778
779    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration PeriodDateBegin
780    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration PeriodDateEnd
781    IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration CumulPeriod
782
783    PeriodDateBegin=$( IGCM_date_ConvertFormatToGregorian ${run_Configuration_PeriodDateBegin} )
784    PeriodDateEnd=$( IGCM_date_ConvertFormatToGregorian ${run_Configuration_PeriodDateEnd} )
785    CumulPeriod=${run_Configuration_CumulPeriod}
786
787    LastPeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate $( IGCM_date_ConvertFormatToGregorian ${PeriodDateBegin} ) -1 )
788
789    if [ ${Period} = 1 ]; then
790      # save last Job output and current run.card
791      typeset Potential
792      IGCM_sys_Cd ${SUBMIT_DIR}
793      #
794      IGCM_debug_Print 2 "Save previous ksh job output"
795      for Potential in $( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.[0-9][0-9][0-9][0-9][0-9][0-9] ) ; do
796        if [ X${Pack} = Xtrue ] ; then
797          ( IGCM_sys_TestFileBuffer  ${R_BUF_KSH}/${Potential} ) || IGCM_sys_Cp ${Potential} ${R_BUF_KSH}/${Potential}.$$
798        else
799          ( IGCM_sys_TestFileArchive ${R_OUT_KSH}/${Potential} ) || IGCM_sys_Cp ${Potential} ${R_OUT_KSH}/${Potential}.$$
800        fi
801      done
802      #
803      IGCM_debug_Print 2 "Save current run.card"
804      IGCM_card_CheckConflict run.card
805      if [ X${Pack} = Xtrue ] ; then
806        IGCM_sys_Cp ${SUBMIT_DIR}/run.card ${R_BUF_KSH}/run.card
807      else
808        IGCM_sys_Cp ${SUBMIT_DIR}/run.card ${R_OUT_KSH}/run.card
809      fi
810      #
811      IGCM_sys_Cd ${RUN_DIR}
812    else
813      unset FileToBeDeleted
814    fi
815
816    # Determine number of day(s) in PeriodLength
817    IGCM_date_GetYearMonthDay $PeriodDateBegin year month day
818    IGCM_config_DaysInPeriodLength
819
820    # Check coherency between (PeriodDateBegin, PeriodDateEnd) and (DateBegin, CumulPeriod, PeriodLength)
821    IGCM_config_DateCoherency
822    # And EXIT if not OK
823    IGCM_debug_Verif_Exit
824
825    # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
826    IGCM_config_StateCheck
827    # And EXIT if not OK
828    IGCM_debug_Verif_Exit
829
830    # We can say we are "Running" now.
831    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Running"
832  fi
833
834  # BEGIN: SHOULD GO IN A FUNCTION FROM libIGCM_date.ksh
835  # Compute year_m1 and year_p1 (year minus 1Y and year plus 1Y)
836  year_m1=$(( year - 1 ))
837  year_p1=$(( year + 1 ))
838  # Compute month_m1 (month minus 1M)
839  # Compute yyyymm_m1 (yyyymm minus 1M)
840  month_m1=$(( 10#${month} - 1 ))
841  if [ ${month_m1} = 0 ]; then
842    month_m1=12
843    yyyymm_m1=${year_m1}12
844  elif [ ${month_m1} -le 9 ]; then
845    month_m1=0${month_m1}
846    yyyymm_m1=${year}${month_m1}
847  else
848    yyyymm_m1=${year}${month_m1}
849  fi
850  # Compute month_p1 (month plus 1M)
851  # Compute yyyymm_p1 (yyyymm plus 1M)
852  month_p1=$(( 10#${month} + 1 ))
853  if [ ${month_p1} = 13 ]; then
854    month_p1=01
855    yyyymm_p1=${year_p1}01
856  elif [ ${month_p1} -le 9 ]; then
857    month_p1=0${month_p1}
858    yyyymm_p1=${year}${month_p1}
859  else
860    yyyymm_p1=${year}${month_p1}
861  fi
862  #IGCM_debug_Print 1 "jg 1 month_m1 = ${month_m1} month_p1 = ${month_p1} "
863  #IGCM_debug_Print 1 "jg 1 calculate yyyymm_m1 = ${yyyymm_m1} "
864  #IGCM_debug_Print 1 "jg 1 calculate yyyymm_p1 = ${yyyymm_p1} "
865
866  #===================================================================#
867  # Calculate CyclicYear to be used for looping over a given forcing  #
868  # period. Add CyclicBegin and CyclicEnd in config.card UserChoices. #
869  #===================================================================#
870
871  # To use the variable CyclicYear, one must add in config.card CyclicBegin and CyclicEnd.
872  # CyclicBegin is the first year in the cycle. CyclicEnd is the last year included in the cycle.
873  if ( [ ! X${config_UserChoices_CyclicBegin} = X ] && [ ! X${config_UserChoices_CyclicEnd} = X ] ) ; then
874    CycleNb=$(( ${config_UserChoices_CyclicEnd} - ${config_UserChoices_CyclicBegin} + 1 ))
875    CyclicYear_p1=NOTDEFINED
876
877    # For current year
878    yeartmp=$year
879    diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
880    while [ $diffy -lt 0 ] ; do
881      yeartmp=$(( ${yeartmp} + ${CycleNb} ))
882      diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
883    done
884    CyclicYear=$(( ( ${diffy} % ${CycleNb} ) + ${config_UserChoices_CyclicBegin} ))
885
886    # For next coming year
887    yeartmp=$(( $year + 1 ))
888    diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
889    while [ $diffy -lt 0 ] ; do
890      yeartmp=$(( ${yeartmp} + ${CycleNb} ))
891      diffy=$(( $yeartmp - ${config_UserChoices_CyclicBegin} ))
892    done
893    CyclicYear_p1=$(( ( ${diffy} % ${CycleNb} ) + ${config_UserChoices_CyclicBegin} ))
894
895    IGCM_debug_Print 1 "CyclicYear   = ${CyclicYear}, CyclicYear_p1 = ${CyclicYear_p1}, current year=$year"
896  else
897    CyclicYear="ERROR_CyclicYear_Variable_Not_Defined"
898    CyclicYear_p1="ERROR_CyclicYear_p1_Variable_Not_Defined"
899    IGCM_debug_Print 1 "CyclicYear wont be use without adding CyclicBegin and CyclicEnd in config.card"
900  fi
901
902  # END: SHOULD GO IN A FUNCTION FROM libIGCM_date.ksh
903
904  #===================================================================#
905  # Prepare variables available for ${COMP}.card and ${COMP}.driver   #
906  #             But available to any son functions                    #
907  #===================================================================#
908
909  # Period Length In Days between DateBegin and DateCurrent (at end of period == PeriodDateEnd !)
910  (( SimulationLengthInDays = $( IGCM_date_DaysBetweenGregorianDate ${PeriodDateEnd} ${DateBegin} ) + 1 ))
911
912  # Debug Print :
913  echo
914  IGCM_debug_Print 1 "IGCM_config_PeriodStart : Before Execution"
915  IGCM_debug_Print 1 "Year of simulation      : ${year}"
916  IGCM_debug_Print 1 "Month of simulation     : ${month}"
917  IGCM_debug_Print 1 "PeriodLengthInDays      : ${PeriodLengthInDays}"
918  IGCM_debug_Print 1 "PeriodDateBegin         : ${PeriodDateBegin}"
919  IGCM_debug_Print 1 "PeriodDateEnd           : ${PeriodDateEnd}"
920  IGCM_debug_Print 1 "SimulationLengthInDays  : ${SimulationLengthInDays}"
921  IGCM_debug_Print 1 "ExperienceLengthInDays  : ${ExperienceLengthInDays}"
922
923  #================================================================#
924  #         Prepare variables available for comp_finalyze          #
925  #================================================================#
926
927  # Period for save files
928  DatesPeriod=${PeriodDateBegin}_${PeriodDateEnd}
929
930  # Prefix for save files of this period
931  PREFIX=${config_UserChoices_JobName}_${DatesPeriod}
932
933  # List of files that will be deleted in RUN_DIR after run
934  [ -f stack ] && FileToBeDeleted[0]="stack"
935
936  # Test if the same run as already been saved :
937  if [ X${JobType} = XRUN ] ; then
938    if [ ${DRYRUN} -le 0 ] ; then
939      if ( IGCM_sys_TestFileBuffer ${R_BUF_KSH}/${PREFIX}_${Exe_Output} ) ; then
940        IGCM_debug_Exit "IGCM_config_PeriodStart" "You are currently RErunning an old job."
941        IGCM_debug_Print 1 "Because of readonly permissions, you can't RErun a job when saved files"
942        IGCM_debug_Print 1 " are still in the ARCHIVE directory. You must deleted those files, or "
943        IGCM_debug_Print 1 " the whole ${R_SAVE} tree. See clean_month.job in ${libIGCM} directory."
944        IGCM_debug_Print 1 " This exit has been initiated because at least ${R_BUF_KSH}/${PREFIX}_${Exe_Output} exists."
945        IGCM_debug_Verif_Exit
946      fi
947    fi
948  else
949    if ( IGCM_sys_TestFileBuffer ${R_BUF_KSH}/${PREFIX}_${Exe_Output} ) ; then
950      IGCM_debug_Print 1 "IGCM_config_PeriodStart" "RErun an old job. Allowed in DEBUG or DEV mode."
951    fi
952  fi
953
954  #================================================================#
955  #       Prepare variables available for binary execution         #
956  #       Call function for creation of run script                 #
957  #       Only done once per job                                   #
958  #================================================================#
959
960  if [ ${Period} -eq 1 ]; then
961    # Define the execution context (MPMD, SPMD, MPI/OMP ...)
962    IGCM_config_ConfigureExecution ${SUBMIT_DIR}/config.card
963    # Create the execution script for the current context
964    IGCM_sys_build_execution_scripts
965  fi
966
967  ExecutionFail=false
968
969  IGCM_debug_PopStack "IGCM_config_PeriodStart"
970}
971
972#===================================
973function IGCM_config_SaveSourceModifications
974{
975  IGCM_debug_PushStack "IGCM_config_SaveSourceModifications"
976
977  typeset ExeOutDateMax listVarEnv
978  ExeOutDateMax=$1
979
980  listVarEnv="ExeOutDateMax,R_OUT_EXE,PREFIX,SUBMIT_DIR"
981  IGCM_sys_RshMaster "\
982    . ${libIGCM}/libIGCM_sys/libIGCM_sys.ksh; \
983    export ExeOutDateMax=${ExeOutDateMax};\
984    export R_OUT_EXE=${R_OUT_EXE};\
985    export PREFIX=${PREFIX};\
986    export SUBMIT_DIR=${SUBMIT_DIR};\
987    export listVarEnv=${listVarEnv};\
988    Script_Output=out_SaveSourceModifications;\
989    IGCM_sys_Qsub ${libIGCM}/SaveSourceModifications.job ${ExeOutDateMax} ${R_OUT_EXE} ${PREFIX} ${SUBMIT_DIR}"
990
991  IGCM_debug_PopStack "IGCM_config_SaveSourceModifications"
992}
993
994#===================================
995function IGCM_config_PeriodEnd
996{
997  IGCM_debug_PushStack "IGCM_config_PeriodEnd"
998
999  echo
1000  IGCM_debug_Print 1 "IGCM_config_PeriodEnd"
1001  echo
1002
1003  if [ ${DRYRUN} -le 1 ] ; then
1004
1005    IGCM_debug_Print 1 "Check components binary : size and creation date"
1006
1007    typeset LS_comp LS_bin ExeDate ExeCpuLog NextExeSize LastCompExeSize
1008    typeset comp i
1009    typeset ExeNameIn ExeNameOut UpdateExe ExeSecDateMax
1010
1011    #==================================#
1012    #        Get last Exe Size         #
1013    #==================================#
1014
1015    (( i=0 ))
1016    if ( ${FirstInitialize} ) ; then
1017      run_Log_LastExeSize=""
1018      for comp in ${config_ListOfComponents[*]} ; do
1019        run_Log_LastExeSize[$i]=0
1020        (( i=i+1 ))
1021      done
1022    else
1023      IGCM_card_DefineArrayFromOption ${SUBMIT_DIR}/run.card Log LastExeSize
1024    fi
1025    #==================================#
1026    #         And Build ExeDate        #
1027    #==================================#
1028
1029    # 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
1030    # 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")
1031    # 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
1032    ExeDate=""
1033    NextExeSize="( "
1034    (( i=0 ))
1035    UpdateExe=false
1036    (( ExeSecDateMax = 0 ))
1037    for comp in ${config_ListOfComponents[*]} ; do
1038
1039      IGCM_debug_Print 3 ${comp}
1040
1041      eval ExeNameIn=\${config_Executable_${comp}[0]}
1042      eval ExeNameOut=\${config_Executable_${comp}[1]}
1043      # Only if we really have an executable for the component :
1044      if [ X${ExeNameIn} = X\"\" ] ; then
1045        # If there is no exe file for this component
1046        (( ExeSize=0 ))
1047      else
1048        LS_bin=${R_EXE}/${ExeNameIn}
1049        IGCM_sys_FileSize ${LS_bin} ExeSize
1050
1051        set +A LS_comp -- $( LC_TIME=en_US ls -l ${LS_bin} )
1052        if [ X${ExeDate} = X ] ; then
1053          # First component exe date
1054          ExeDate=${comp}_${LS_comp[5]}_${LS_comp[6]}
1055        else
1056          ExeDate=${ExeDate}-${comp}_${LS_comp[5]}_${LS_comp[6]}
1057        fi
1058        ExeDate=${ExeDate}_${LS_comp[7]}
1059      fi
1060
1061      if [ ${i} -eq 0 ] ; then
1062        # First component
1063        NextExeSize="( "${ExeSize}
1064      else
1065        NextExeSize=${NextExeSize}", "${ExeSize}
1066      fi
1067      LastCompExeSize=${run_Log_LastExeSize[$i]}
1068      (( i=i+1 ))
1069
1070      if [ ${ExeSize} -ne ${LastCompExeSize} ] ; then
1071        if ( ${FirstInitialize} ) ; then
1072          IGCM_debug_Print 1 "Save first ${ExeNameIn} in ${R_OUT_EXE} !"
1073        else
1074          IGCM_debug_Print 1 "${ExeNameIn} has changed in ${R_EXE} !"
1075          IGCM_debug_Print 1 "Save latest ${ExeNameIn} in ${R_OUT_EXE} !"
1076          FileToBeDeleted[${#FileToBeDeleted[@]}]=${ExeNameOut}
1077        fi
1078        IGCM_sys_Put_Out ${ExeNameOut} ${R_OUT_EXE}/${PREFIX}_${ExeNameIn} rw
1079        UpdateExe=true
1080
1081        # SD : switch off for now
1082        #IGCM_sys_GetDate_FichWork ${LS_bin} ExeSecDate
1083        #if [ $ExeSecDateMax -lt $ExeSecDate ] ; then
1084        #  ExeSecDateMax=$ExeSecDate
1085        #fi
1086      fi
1087    done
1088
1089    # SD : switch off for now
1090    #if ( ${UpdateExe} ) ; then
1091    #  echo "Launch SaveSourceModifications."
1092    #  IGCM_config_SaveSourceModifications ${ExeSecDateMax}
1093    #fi
1094
1095    NextExeSize=${NextExeSize}" )"
1096    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Log LastExeSize "${NextExeSize}"
1097
1098    if [ ${DRYRUN} -le 1 ] ; then
1099      tail -1500 ${Exe_Output} > ${Exe_Output}_tail.txt
1100      ExeCpuLog=$( gawk -f ${libIGCM}/libIGCM_sys/IGCM_add_out.awk ${Exe_Output}_tail.txt )
1101      RET=$?
1102      if [ $RET -eq 0 ] ; then
1103        # ExeCpuLog variable contents 5 fields
1104        echo "${CumulPeriod} ${PeriodDateBegin} ${PeriodDateEnd} ${ExeCpuLog} ${ExeDate}" |   \
1105          gawk '{printf("# %11d | %15s | %15s | %19s | %19s | %15.5f | %15.5f | %15.5f | %s\n", \
1106            $1,$2,$3,$4,$5,$6,$7,$8,$9)}' >> ${SUBMIT_DIR}/run.card
1107      fi
1108      FileToBeDeleted[${#FileToBeDeleted[@]}]=${Exe_Output}_tail.txt
1109    fi
1110
1111  fi
1112
1113  #==================================#
1114  #         Save Job output          #
1115  #==================================#
1116  if [ X${Pack} = Xtrue ] ; then
1117    IGCM_sys_PutBuffer_Out ${Exe_Output} ${R_BUF_KSH}/${PREFIX}_${Exe_Output}
1118  else
1119    IGCM_sys_Put_Out ${Exe_Output} ${R_OUT_KSH}/${PREFIX}_${Exe_Output}
1120  fi
1121  FileToBeDeleted[${#FileToBeDeleted[@]}]=${Exe_Output}
1122
1123  # All was right ? no ? then we stop.
1124  IGCM_debug_Verif_Exit
1125
1126  # If all was OK, we can delete all files not necessary for next Job
1127  echo
1128  IGCM_debug_Print 1 "Files that will be deleted before next period-run : "
1129
1130  if [ ${DRYRUN} -le 2 ] ; then
1131    for f in ${FileToBeDeleted[@]} ; do [ -f ${f} ] && ls -la $f ; [ -f ${f} ] && rm -f $f ; done
1132  else
1133    echo ${FileToBeDeleted[@]}
1134  fi
1135
1136  # Send some accounting element to the user if CumulPeriod=3
1137  if [ ${CumulPeriod} -eq 3 ] ; then
1138    echo
1139    IGCM_debug_Print 1 "Send email containing some accounting information : "
1140
1141    RealCpuTime=$( echo ${ExeCpuLog} | gawk '{print $3}' )
1142
1143    consumeHoursPerPeriod=$( echo "scale=6;${RealCpuTime}*${coreNumber}/3600" | bc )
1144
1145    consumeHoursPerWholeSimulation=$( echo "scale=6;${consumeHoursPerPeriod}/${PeriodLengthInDays}*${ExperienceLengthInDays}" | bc )
1146
1147    recommendedPeriodNb=$( echo "scale=6;${jobWarningDelay}/3600/${consumeHoursPerPeriod}*${coreNumber}" | bc )
1148
1149    IGCM_sys_SendMail Accounting
1150  fi
1151
1152  #=================================================#
1153  #         Modification of libIGCM behaviour       #
1154  #=================================================#
1155
1156  # To use this function, one must copy libIGCM.card from ${libIGCM} directory
1157  # and put it in ${SUBMIT_DIR} directory. After modifications of ${SUBMIT_DIR}/libIGCM.card,
1158  # variables define inside [UserChanges] will be modified for next Period of libIGCM main loop.
1159  if [ -f ${SUBMIT_DIR}/libIGCM.card ] ; then
1160    echo
1161    echo "########################################################################"
1162    echo "!!!                 Modification of libIGCM behaviour                !!!"
1163    echo
1164
1165    IGCM_debug_Print 1 "DefineArrayFromOption  : libIGCM_UserChanges in libIGCM.card"
1166    IGCM_card_DefineArrayFromSection ${SUBMIT_DIR}/libIGCM.card UserChanges
1167    IGCM_debug_Print 2 "libIGCM_UserChanges" ${libIGCM_UserChanges[*]}
1168
1169    # Special treatments for libIGCM internals
1170    for option in ${libIGCM_UserChanges[*]} ; do
1171      IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/libIGCM.card UserChanges ${option}
1172
1173      echo "We will change : ${option}."
1174      eval echo "Previous value : " \${${option}}
1175      eval echo "Change to : " \${libIGCM_UserChanges_${option}}
1176
1177      eval ${option}=\${libIGCM_UserChanges_${option}}
1178
1179      case ${option} in
1180      config_UserChoices_DateEnd)
1181        IGCM_debug_PrintVariables 1 config_UserChoices_DateEnd
1182        DateEnd=$( IGCM_date_ConvertFormatToGregorian ${config_UserChoices_DateEnd} )
1183
1184        # Period Length In Days between DateBegin and DateEnd
1185        (( ExperienceLengthInDays=$( IGCM_date_DaysBetweenGregorianDate ${DateEnd} ${DateBegin} )  + 1 ))
1186        if [ ${ExperienceLengthInDays} -lt 0 ] ; then
1187          IGCM_debug_Print 1 "Problem with dates in libIGCM.card : ${DateEnd} < ${DateBegin} ! You must check that."
1188          IGCM_debug_Exit "IGCM_PeriodEnd have wrong dates."
1189          IGCM_debug_Verif_Exit
1190        fi
1191        ;;
1192      config_UserChoices_PeriodLength)
1193        IGCM_debug_Print 1  "Change config_UserChoices_PeriodLength=${config_UserChoices_PeriodLength}"
1194        ;;
1195      PeriodNb)
1196        IGCM_debug_Print 1  "Loop in main Job with ${PeriodNb} period(s)"
1197        ;;
1198      config_Post_RebuildFrequency)
1199        IGCM_debug_Print 1  "Change config_Post_RebuildFrequency=${config_Post_RebuildFrequency} : IGCM_post_Configure"
1200        IGCM_post_Configure
1201        ;;
1202      config_Post_TimeSeriesFrequency)
1203        IGCM_debug_Print 1  "Change config_Post_TimeSeriesFrequency = ${config_Post_TimeSeriesFrequency} : IGCM_post_Configure"
1204        IGCM_post_Configure
1205        ;;
1206      config_Post_SeasonalFrequency)
1207        IGCM_debug_Print 1  "Change config_Post_SeasonalFrequency = ${config_Post_SeasonalFrequency} : IGCM_post_Configure"
1208        IGCM_post_Configure
1209        ;;
1210      esac
1211    done
1212
1213    echo
1214    echo "########################################################################"
1215    echo
1216  fi
1217
1218  #=================================================#
1219  #         Determine next computed period          #
1220  #=================================================#
1221
1222  PeriodDateBegin=$( IGCM_date_AddDaysToGregorianDate ${PeriodDateEnd} 1 )
1223  IGCM_date_GetYearMonthDay $PeriodDateBegin year month day
1224  year_m1=$(( year - 1 ))
1225  year_p1=$(( year + 1 ))
1226  IGCM_config_DaysInPeriodLength
1227  PeriodDateEnd=$( IGCM_date_AddDaysToGregorianDate ${PeriodDateBegin} $(( ${PeriodLengthInDays} - 1 )) )
1228
1229  # Debug Print :
1230  echo
1231  IGCM_debug_Print 1 "IGCM_config_PeriodEnd : Preparing Next Execution"
1232  IGCM_debug_Print 1 "PeriodDateBegin       : ${PeriodDateBegin}"
1233  IGCM_debug_Print 1 "PeriodDateEnd         : ${PeriodDateEnd}"
1234  IGCM_debug_Print 1 "PeriodLengthInDays    : ${PeriodLengthInDays}"
1235
1236  PeriodDateBegin=$( IGCM_date_ConvertFormatToHuman ${PeriodDateBegin} )
1237  PeriodDateEnd=$( IGCM_date_ConvertFormatToHuman ${PeriodDateEnd} )
1238
1239  (( CumulPeriod = CumulPeriod + 1 ))
1240
1241  # Debug Print :
1242  echo
1243  IGCM_debug_Print 3 "PeriodDateBegin Human : ${PeriodDateBegin}"
1244  IGCM_debug_Print 3 "PeriodDateEnd Human   : ${PeriodDateEnd}"
1245  IGCM_debug_Print 3 "CumulPeriod           : ${CumulPeriod}"
1246
1247  #=================================================#
1248  #             Write updated run.card              #
1249  #=================================================#
1250
1251  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateBegin ${PeriodDateBegin}
1252  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodDateEnd ${PeriodDateEnd}
1253  IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration CumulPeriod ${CumulPeriod}
1254
1255  if ( ${FirstInitialize} ) ; then
1256    # It's no more the first time
1257    FirstInitialize=false
1258  fi
1259
1260  IGCM_debug_PopStack "IGCM_config_PeriodEnd"
1261}
1262
1263#===================================
1264function IGCM_config_Finalize
1265{
1266  IGCM_debug_PushStack "IGCM_config_Finalize"
1267
1268  echo
1269  IGCM_debug_Print 1 "IGCM_config_Finalize"
1270  echo
1271
1272  # Test state of run in run.card. Will schedule an exit if another process setted it to "Fatal"
1273  IGCM_config_StateCheck
1274
1275  # And EXIT if not OK
1276  IGCM_debug_Verif_Exit
1277
1278  if [ ${SimulationLengthInDays} -ge ${ExperienceLengthInDays} ] ; then
1279    #==========================#
1280    # End of entire simulation #
1281    #==========================#
1282    simulationIsOver=true
1283
1284    # Mail notification
1285    IGCM_sys_SendMail
1286    #
1287    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Completed"
1288    #
1289    IGCM_debug_Print 1 "Normal End of computation."
1290
1291  else
1292    #=================#
1293    # Submit next job #
1294    #=================#
1295    simulationIsOver=false
1296
1297    IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "OnQueue"
1298
1299    # Name of next Ksh Script output :
1300    Script_Output=${Script_Output_Prefix}_${config_UserChoices_JobName}.$( printf "%06d" ${CumulPeriod} )
1301
1302    IGCM_debug_Print 1 "Submit next job"
1303    # SUBMIT NEXT JOB from SUBMIT_DIR and come back in RUN_DIR
1304    IGCM_sys_Cd ${SUBMIT_DIR}
1305    # Keep only the 5 latest ${Script_Output_Prefix}_${config_UserChoices_JobName}
1306    ScriptTot=$( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.?????? 2>/dev/null | wc -l )
1307    [ ${ScriptTot} -gt 5 ] && rm -f $( ls ${Script_Output_Prefix}_${config_UserChoices_JobName}.?????? | head -$(( ${ScriptTot} - 5 )) )
1308    # Submit next job and come back
1309    IGCM_sys_Qsub ${SUBMIT_DIR}/Job_${config_UserChoices_JobName}
1310    IGCM_sys_Cd -
1311  fi
1312
1313  # Clean ${RUN_DIR}=${RUN_DIR_PATH}/${config_UserChoices_JobName}.${$}
1314  # Only for production run (No clean up in DEV or DEB mode)
1315  # and command sent from .. directory.
1316  IGCM_sys_Cd ..
1317  [ X${JobType} = XRUN ] && IGCM_sys_RmRunDir -rf ${RUN_DIR_PATH}
1318
1319  # Inform the rabbitMQ queue
1320  IGCM_debug_BigBro_Finalize
1321
1322  IGCM_debug_PopStack "IGCM_config_Finalize"
1323}
1324
1325#===================================
Note: See TracBrowser for help on using the repository browser.