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

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