source: trunk/libIGCM/ins_job @ 1303

Last change on this file since 1303 was 1303, checked in by mafoipsl, 8 years ago

For curie, force node used in post-processing jobs to standard and delete related questions.

  • Property svn:executable set to *
  • Property svn:keywords set to Revision Author Date
File size: 13.4 KB
Line 
1#!/bin/ksh
2
3#**************************************************************
4# Author: Jacques Belier
5# Contact:
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#- Installation of jobs according to environment
15#---------------------------------------------------------------------
16function ins_job_Usage
17{
18print - "
19ins_job installs the jobs in the directories
20which contain a file config.card
21
22ins_job must be launched on the host
23on which the job will be submitted
24
25Usage :
26  ${b_n} [-h] [-v] [-e]
27  or on curie/TGCC :
28  ${b_n} [-h] [-v] [-e] [-p project] [-c number of cores]
29
30Options :
31  -h                  : help
32  -v                  : verbose mode
33  -e                  : turn on ensemble mode (hindcast/forecast or date restart)
34on curie only :
35  -p project          : add default project on curie
36  -c number of cores  : add default number of cores for postprocessing on curie 1-16 or 1-128
37"
38}
39function ins_job_Warning
40{
41   [[ ${x_v} = 'verbose' ]] && print - "\n############### WARNING ###############";
42   [[ ${x_v} = 'verbose' ]] && print - "File ${n_f} already exists\nin directory ${j}";
43   [[ ${x_v} = 'verbose' ]] && print - "You must delete this file to update !";
44}
45
46function ins_job_Check_JobName
47{
48  verif=${JobName##[a-zA-Z]*(?([.\-])[a-zA-Z0-9])}
49
50  if [ ${#verif} -ne 0 ] ; then
51    echo "################ ERROR ################"
52    echo "${JobName} is invalid."
53    echo "- JobName can only contain alphanumeric characters, \".\" and \"-\""
54    echo "- JobName must start with a letter"
55
56    ((NbErr=NbErr+1))
57
58    Status=1
59  else
60    Status=0
61  fi
62
63  return ${Status}
64}
65
66#-
67#     dirname     and      basename
68#-
69d_n=$(dirname ${0}); b_n=$(basename ${0});
70#-
71# Retrieving and validation of the options
72#-
73x_v='silencious';
74x_e=false;
75x_p=false;
76x_q=false;
77x_c=false;
78while getopts :hvec:p:q: V ; do
79  case $V in
80  (h)  ins_job_Usage; exit 0;;
81  (v)  x_v='verbose';;
82  (e)  x_e=true;;
83  (p)  x_p=true
84       ProjectID=${OPTARG} ;;
85  (c)  x_c=true
86       ProjectCore=${OPTARG} ;;
87  (:)  echo ${b_n}" : -"${OPTARG}" option : missing value" 1>&2;
88       exit 2;;
89  (\?) echo ${b_n}" : -"${OPTARG}" option : not supported" 1>&2;
90       exit 2;;
91  esac
92done
93[ ${x_v} = 'silencious' ] && export DEBUG_sys=false
94shift $(($OPTIND-1));
95#-
96# Define working files
97#-
98F_MOD=$(cd ${d_n}'/..';/bin/pwd;)
99# [[ ${F_MOD##*/} != 'modipsl' ]] && \
100#  { print - "directory 'modipsl' unreachable"; exit 3; }
101W_W=${d_n}'/../libIGCM'
102[[ ! -d ${W_W} ]] && { print - "${W_W} unreachable"; exit 3; }
103libIGCM=$(cd ${W_W};/bin/pwd;)
104F_JOB=${libIGCM}'/AA_job';
105[[ ! -f ${F_JOB} ]] && { print - "${F_JOB} unreachable"; exit 3; }
106F_RCI=${libIGCM}'/run.card.init';
107[[ ! -f ${F_RCI} ]] && { print - "${F_RCI} unreachable"; exit 3; }
108#-
109# Accessing to functions (without stack)
110#-
111# No verbosity (0, 1, 2, 3)
112Verbosity=0
113# No de debug
114DEBUG_debug=false
115# Dont move libIGCM
116MirrorlibIGCM=false
117# Behave like computing job
118TaskType=computing
119# Source libIGCM
120. ${libIGCM}/libIGCM_debug/libIGCM_debug.ksh
121. ${libIGCM}/libIGCM_card/libIGCM_card.ksh
122. ${libIGCM}/libIGCM_date/libIGCM_date.ksh
123. ${libIGCM}/libIGCM_sys/libIGCM_sys.ksh
124. ${libIGCM}/libIGCM_config/libIGCM_config.ksh
125if [ $x_e = 'true' ] ; then
126  . ${libIGCM}/libIGCM_ensemble/libIGCM_ensemble.ksh
127fi
128
129#-
130[[ ${x_v} = 'verbose' ]] && \
131 {
132  print - "";
133  print - '--- Host        : '${SYSTEM};
134  print - '--- modipsl     : '${F_MOD};
135  print - '--- libIGCM     : '${libIGCM};
136  print - '--- basic job   : '${F_JOB};
137  print - '--- basic card  : '${F_RCI};
138 }
139#-
140[[ ${x_v} = 'verbose' ]] && print - "\nInstallation of jobs for '${SYSTEM}'";
141#-
142
143NbErr=0
144
145#-
146# Define Project parameters to set up jobs header for Curie (TGCC)
147# on curie define ProjectID  and ProjectCore : option or answer
148# on curie ProjectNode forced to standard since 16/3/2016
149#-
150
151if [ X"${SYSTEM}" == "Xcurie" ] ; then
152  if ( ! ${x_p} ) ; then
153    ProjectID=$( ccc_myproject | gawk '{ if ( $3 ~ /^project$/ && $4 !~ /^tgcc/ ) { print $4 } }' | head -n 1 )
154    ProjectID=${ProjectID:="gencmip6"}
155    answer=""
156    print - "Hit Enter or give project ID (default is ${ProjectID}), possible projects are $( echo $( ccc_myproject | gawk '{ if ( $3 ~ /^project$/ && $4 !~ /^tgcc/ ) { print $4 } }' | sort -u ) ) :"
157    read answer
158
159    if [ "X${answer}" != "X" ] ; then
160      ProjectID=${answer}
161    fi
162  fi # if ( ! ${x_p} )
163
164  #- ProjectNode forced to standard since 16/3/2016
165  ProjectNode="standard"
166
167  echo  ProjectID is ${ProjectID} and ProjectNode for PostProcessing is ${ProjectNode}
168
169  #- ProjectNode is known (standard since 16/3/2016) set ProjectCoreMax
170  ProjectCoreMax="16"
171
172  if ( ! ${x_c} ) ; then
173    #- ProjectNode is known (standard since 16/3/2016), set ProjectCore to default or answer
174    ProjectCore="4"
175    answerOK=false
176
177    while ( ! ${answerOK} ) ; do
178      answer=""
179      print - "Hit Enter or give NUMBER OF CORES required for post-processing (default is \"${ProjectCore}\"), possible numbers of cores are \"1\" to \"${ProjectCoreMax}\" : "
180      read answer
181      [ "X${answer}" == "X" ] || [ ${answer} -ge 1 -a ${answer} -le ${ProjectCoreMax} ] && answerOK=true
182    done
183
184    if [ "X${answer}" != "X" ] ; then
185      ProjectCore=${answer}
186    fi
187
188  fi # if ( ! ${x_c} )
189
190  echo ProjectCore is ${ProjectCore}
191  #- ProjectCore is set (option or answer)
192
193else
194  echo No option for Header regarding ProjectID, ProjectNode and ProjectCore because we are not on curie
195fi # if [ X"${SYSTEM}" == "Xcurie" ]
196
197#-
198# Define the pattern string to substitute
199#-
200W_P='#-Q- '; W_W=${W_P}${SYSTEM};
201#-
202# Extract list of 'config.card' files
203# and create jobs with AA_job
204#-
205F_CFG='config.card';
206F_CFG_ENS='ensemble.card';
207SUBMIT_DIR_ENS=$( pwd )
208for i in $( pwd )/config.card
209do
210  if [ ! -f $i ] ; then
211    echo ""
212    echo "################## WARNING ##################"
213    echo "No config.card available in current directory"
214    echo ""
215    continue
216  fi
217
218
219  j=$(cd ${i%/*};/bin/pwd;)
220  n_f=${F_RCI##*/};
221
222  if [ ! X$( echo ${j} | grep EXPERIMENTS ) = X ] ; then
223    # Do not treat config.card if it is in sub-directory of EXPERIMENTS
224    # Continue to next config.card
225    continue
226  else
227    [[ ${x_v} = 'verbose' ]] && print - "\nWorking with file ${F_CFG}\nin directory ${j}\nfor ${n_f}";
228  fi
229
230  # Find out if new structure and set .resol filename
231  if [ -d ${j}/EXPERIMENTS ] && [ -d ${j}/GENERAL ] ; then
232    # New Structure
233    [[ ${x_v} = 'verbose' ]] && echo "This is new configuration structure"
234    new_struct=yes
235    resolfile=$j/.resol
236  else
237    # Old Structure
238    new_struct=no
239    resolfile=$j/../.resol
240  fi
241
242  # Get all variables declared in section UserChoices in config.card
243  IGCM_card_DefineArrayFromSection ${j}'/'${F_CFG} UserChoices
244  # Set default values
245  config_UserChoices_ExpType=""
246  RESOL_ATM_3D=this_is_a_test_string
247  RESOL=this_is_another_test_string
248  typeset option
249  for option in ${config_UserChoices[*]} ; do
250    IGCM_card_DefineVariableFromOption ${j}'/'${F_CFG} UserChoices ${option}
251  done
252
253  # Find the JobName : JobName might contain the variable RESOL_ATM_3D that will be replaced by what is in .resol file
254  if [ ! X$( echo ${config_UserChoices_JobName} | grep ${RESOL_ATM_3D} ) = X ] ; then
255    TRUERESOL=$( tail -1 $resolfile | awk "-F=" '{print $2}' )
256    echo TRUERESOL = $TRUERESOL
257    JobName=$( echo ${config_UserChoices_JobName} | sed -e "s/${RESOL_ATM_3D}/${TRUERESOL}/" )
258    IGCM_card_WriteOption ${j}'/'${F_CFG} UserChoices JobName ${JobName}
259  elif [ ! X$( echo ${config_UserChoices_JobName} | grep ${RESOL} ) = X ] ; then
260    TRUERESOL=$( head -1 $resolfile  )
261    JobName=$( echo ${config_UserChoices_JobName} | sed -e "s/${RESOL}/${TRUERESOL}/" )
262    IGCM_card_WriteOption ${j}'/'${F_CFG} UserChoices JobName ${JobName}
263  else
264    JobName=${config_UserChoices_JobName}
265  fi
266
267  # Check JobName validity : only alphanumerical characters, "-" and "." are authorized
268  ins_job_Check_JobName
269  RetCode=$?
270  [[ $RetCode -gt 0 ]] && continue
271
272  [[ ${x_v} = 'verbose' ]] && echo "JobName=${JobName}"
273
274  # Add specific treatment for new type of directory structure
275  if [ ${new_struct} == yes ] ; then
276
277    if [ "X${config_UserChoices_ExpType}" = X ] ; then
278      echo "\nERROR in ${j}/config.card"
279      echo "ins_job stops here"
280      echo "=> The variable ExpType must be added in config.card in section UserChoices"
281      echo "=> ExpType gives the directory for the .card configuration files for the wanted experiement. For exemple ExpType=IPSLCM5/historical"
282      exit 4
283    else
284      [[ ${x_v} = 'verbose' ]] && echo "ExpType= ${config_UserChoices_ExpType}"
285    fi
286
287    if [ -d ${j}/${JobName} ] ; then
288      echo "Directory ${j}/${JobName} exist already, continue next config.card"
289      continue
290    fi
291    echo "=> Submit directory ${JobName} will be created with cards from EXPERIMENTS/${config_UserChoices_ExpType}"
292    cp -r ${j}/EXPERIMENTS/${config_UserChoices_ExpType} ${j}/${JobName}
293    cp -r ${j}/GENERAL/* ${j}/${JobName}/.
294    cp -f ${j}/${F_CFG}  ${j}/${JobName}/.
295    if [ -f ${F_CFG_ENS} ] ; then
296      cp -f ${j}/${F_CFG_ENS}  ${j}/${JobName}/.
297      SUBMIT_DIR_ENS=${j}/${JobName}
298    fi
299    rm -f ${j}/${F_CFG}
300    rm -f ${j}/${F_CFG_ENS}
301    rm -f ${j}/${F_CFG}.bak
302    j=${j}/${JobName}
303    [[ ${x_v} = 'verbose' ]] && echo new j=$j
304  fi
305  # end specific treatment for new type directory structure
306
307  [[ -f ${j}'/'${n_f} ]] && { ins_job_Warning; } || \
308   {
309    [[ ${x_v} = 'verbose' ]] && print - "\nCopying file ${F_RCI}\nin directory ${j}";
310    \cp ${F_RCI} ${j};
311   }
312
313  #==================================
314  # Read ListOfComponents section:
315  #echo
316  #IGCM_debug_Print 1 "DefineArrayFromSection : ListOfComponents"
317
318  IGCM_card_DefineArrayFromSection  ${j}'/'${F_CFG} ListOfComponents
319  for comp in ${config_ListOfComponents[*]} ; do
320    IGCM_card_DefineArrayFromOption  ${j}'/'${F_CFG} ListOfComponents ${comp}
321  done
322  #IGCM_debug_Print 3 ${config_ListOfComponents[*]}
323
324  #==================================
325  # Read Executable section:
326  IGCM_card_DefineArrayFromSection ${j}'/'${F_CFG} Executable
327
328  # Define the execution context (MPMD, SPMD, MPI/OMP ...)
329  IGCM_config_ConfigureExecution ${j}'/'${F_CFG}
330
331  # coreNumber    : TOTAL NUMBER OF CORES
332  # mpiTasks      : TOTAL NUMBER OF MPI TASKS
333  # openMPthreads : NUMBER OF OpenMP THREADS
334
335  # File name for Job
336  n_f='Job_'${JobName};
337  [[ -f ${j}'/'${n_f} ]] && { ins_job_Warning; continue; }
338  [[ ${x_v} = 'verbose' ]] && print - "\nWorking with file ${F_CFG}\nin directory ${j}\nfor ${n_f}";
339  sed -e "/^${W_W} */ s///" \
340      -e "/^${W_P}/d"       \
341      -e "s%::modipsl::%${F_MOD}%" \
342      -e "s/::Jobname::/${JobName}/" \
343      -e "s/::default_project::/${ProjectID}/" \
344      ${F_JOB} > ${j}'/'${n_f}
345  chmod u+x ${j}'/'${n_f}
346
347  # update Headers so that ressources description are accurate (MPMD/SPMD/...)
348  IGCM_sys_updateHeaders ${j}'/'${n_f}
349done
350
351#-
352# Extract list of AA_* files in libIGCM
353# and create jobs (for all except AA_job)
354#-
355for i in $(find ${libIGCM} -maxdepth 1 -name "AA_*" -print)
356do
357  i_f=${i##*/};
358  [[ ${i_f} = 'AA_job' ]] && { continue; }
359  j=${i%/*}; n_f=${i_f#AA_}'.job';
360  [[ -f ${j}'/'${n_f} ]] && { ins_job_Warning; continue; }
361  [[ ${x_v} = 'verbose' ]] && print - "\nIn directory ${j}\n${i_f} -> ${n_f}"
362  sed -e "/^${W_W} */ s///" \
363      -e "s%::modipsl::%${F_MOD}%" \
364      -e "/^${W_P}/d"       \
365      -e "s/::default_node::/${ProjectNode}/" \
366      -e "s/::default_core::/${ProjectCore}/" \
367      -e "s/::default_project::/${ProjectID}/" \
368      ${i} > ${j}'/'${n_f}
369  chmod u+x ${j}'/'${n_f}
370done
371#-
372# set default_project in libIGCM_sys_curie.ksh too.
373#-
374if [ X"${SYSTEM}" == "Xcurie" ] ; then
375  i=${libIGCM}/libIGCM_sys/libIGCM_sys_curie.ksh
376  sed -i -e "s/::default_project::/${ProjectID}/" ${i}
377fi
378#-
379# Limited to hindcast/forecast and date restart Ensemble for the time being
380if [ ${x_e} = 'true' ] ; then
381  #.. Read input data from ensemble.card ..
382  SUBMIT_DIR=${SUBMIT_DIR_ENS}
383  RUN_DIR="${WORKDIR}/ENSEMBLE"
384  #
385  # Copy initial things around and define variables (hindcast/forecast case)
386  IGCM_sys_Cd ${SUBMIT_DIR}
387  IGCM_ensemble_Init
388
389  if [[ ${ensemble_Ens_PARAMETRIC_active} = 'y' ]] ; then
390    echo "WARNING: Parametric Ensemble is not implemented yet..."
391  fi
392
393  if [[ ${ensemble_Ens_DATE_active} = 'y' ]] ; then
394    IGCM_sys_Cd ${SUBMIT_DIR}
395    IGCM_ensemble_DateInit
396    # As it says
397    IGCM_sys_Cd ${SUBMIT_DIR}
398    IGCM_ensemble_DatePeriodicStarts
399    # As it says
400    IGCM_sys_Cd ${SUBMIT_DIR}
401    IGCM_ensemble_DateNonPeriodicStarts
402    # Clean
403    IGCM_sys_Rm -rf ${RUN_DIR}
404  fi
405
406  if [[ ${ensemble_Ens_PERTURB_active} = 'y' ]] ; then
407    IGCM_sys_Cd ${SUBMIT_DIR}
408    IGCM_ensemble_CastInit
409    # As it says
410    IGCM_sys_Cd ${SUBMIT_DIR}
411    IGCM_ensemble_CastPeriodicStarts
412    # As it says
413    IGCM_sys_Cd ${SUBMIT_DIR}
414    IGCM_ensemble_CastNonPeriodicStarts
415    # As it says
416    IGCM_sys_Cd ${SUBMIT_DIR}
417    IGCM_ensemble_CastMemberList
418    # Done
419    IGCM_sys_Cp ${RUN_DIR}/CreatedDir.txt ${SUBMIT_DIR}
420    IGCM_sys_Cd ${SUBMIT_DIR}
421    # Clean
422    IGCM_sys_Rm -rf ${RUN_DIR}
423  fi
424fi
425#-
426[[ ${x_v} = 'verbose' ]] && print - "";
427#-
428# That's all folks
429#-
430
431if [ ${NbErr} -ne 0 ] ; then
432  echo "################ ERROR ################"
433  echo "${NbErr} invalid JobName(s) found, check the log"
434fi
435
436
437exit 0;
Note: See TracBrowser for help on using the repository browser.