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

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