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

Last change on this file since 1412 was 1410, checked in by sdipsl, 7 years ago
  • #326 fix the issue when SPACENAME = TEST
  • use a safer ksh syntax for testing equality
  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

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