source: trunk/libIGCM/ins_job @ 1470

Last change on this file since 1470 was 1470, checked in by mafoipsl, 6 years ago

For ins_job :

  • delete actions done for curie
  • for irene, set default postprocessing node to xlarge
  • for irene add the list of cmip6 sous-imputation instead of gencmip6. i (it takes some times. Message added : Wait for the next question ...)
  • Property svn:executable set to *
  • Property svn:keywords set to Revision Author Date
File size: 17.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  or on irene/TGCC :
30  ${b_n} [-h] [-v] [-e] [-p project] [-s post-project] [-q type_of_node] [-c number of cores]
31  or on ada /IDRIS
32  ${b_n} [-h] [-v] [-e] [-m MPI environment]
33Options :
34  -h                  : help
35  -v                  : verbose mode
36  -e                  : turn on ensemble mode (hindcast/forecast or date restart)
37  -f                  : ins_job is force to create jobs even if they already exist
38on irene only :
39  -p project          : add default project on irene
40  -s post-project     : add default project use for post-processing on irene
41  -q type_of_node     : add default type of nodes for postprocessing on irene skylake/xlarge
42  -c number of cores  : add default number of cores for postprocessing on irene 1-112
43on ada only :
44  - m MPI environment : add default MPI environment (Intel MPI or IBM MPI)
45"
46}
47function ins_job_Warning
48{
49   [[ ${x_v} = 'verbose' ]] && print - "\n############### WARNING ###############";
50   [[ ${x_v} = 'verbose' ]] && print - "File ${n_f} already exists\nin directory ${j}";
51   [[ ${x_v} = 'verbose' ]] && print - "You must delete this file to update !";
52}
53
54function ins_job_Check_JobName
55{
56  verif=${JobName##[a-zA-Z]*(?([.\-])[a-zA-Z0-9])}
57
58  if [ ${#verif} -ne 0 ] ; then
59    echo "################ ERROR ################"
60    echo "${JobName} is invalid."
61    echo "- JobName can only contain alphanumeric characters, \".\" and \"-\""
62    echo "- JobName must start with a letter"
63
64    ((NbErr=NbErr+1))
65
66    Status=1
67  else
68    Status=0
69  fi
70
71  return ${Status}
72}
73
74#-
75#     dirname     and      basename
76#-
77d_n=$(dirname ${0}); b_n=$(basename ${0});
78#-
79# Retrieving and validation of the options
80#-
81x_v='silencious';
82x_e=false;
83x_f=false;
84x_p=false;
85x_q=false;
86x_s=false;
87x_c=false;
88x_m=false;
89while getopts :hvefc:p:m:q:s: V ; do
90  case $V in
91  (h)  ins_job_Usage; exit 0;;
92  (v)  x_v='verbose';;
93  (e)  x_e=true;;
94  (f)  x_f=true;;
95  (p)  x_p=true
96       ProjectID=${OPTARG} ;;
97  (s)  x_s=true
98       PostID=${OPTARG} ;;
99  (q)  x_q=true
100       ProjectNode=${OPTARG} ;;
101  (c)  x_c=true
102       ProjectCore=${OPTARG} ;;
103  (m)  x_m=true
104       MPIEnvironment=${OPTARG} ;;
105  (:)  echo ${b_n}" : -"${OPTARG}" option : missing value" 1>&2;
106       exit 2;;
107  (\?) echo ${b_n}" : -"${OPTARG}" option : not supported" 1>&2;
108       exit 2;;
109  esac
110done
111[ ${x_v} = 'silencious' ] && export DEBUG_sys=false
112shift $(($OPTIND-1));
113#-
114# Define working files
115#-
116F_MOD=$(cd ${d_n}'/..';/bin/pwd;)
117# [[ ${F_MOD##*/} != 'modipsl' ]] && \
118#  { print - "directory 'modipsl' unreachable"; exit 3; }
119W_W=${d_n}'/../libIGCM'
120[[ ! -d ${W_W} ]] && { print - "${W_W} unreachable"; exit 3; }
121libIGCM=$(cd ${W_W};/bin/pwd;)
122F_JOB=${libIGCM}'/AA_job';
123[[ ! -f ${F_JOB} ]] && { print - "${F_JOB} unreachable"; exit 3; }
124F_RCI=${libIGCM}'/run.card.init';
125[[ ! -f ${F_RCI} ]] && { print - "${F_RCI} unreachable"; exit 3; }
126#-
127# Accessing to functions (without stack)
128#-
129# No verbosity (0, 1, 2, 3)
130Verbosity=0
131# No de debug
132DEBUG_debug=false
133# Dont move libIGCM
134MirrorlibIGCM=false
135# Behave like computing job
136TaskType=computing
137# Source libIGCM
138. ${libIGCM}/libIGCM_debug/libIGCM_debug.ksh
139. ${libIGCM}/libIGCM_card/libIGCM_card.ksh
140. ${libIGCM}/libIGCM_date/libIGCM_date.ksh
141. ${libIGCM}/libIGCM_sys/libIGCM_sys.ksh
142. ${libIGCM}/libIGCM_config/libIGCM_config.ksh
143if [ $x_e = 'true' ] ; then
144  . ${libIGCM}/libIGCM_ensemble/libIGCM_ensemble.ksh
145fi
146
147#-
148[[ ${x_v} = 'verbose' ]] && \
149 {
150  print - "";
151  print - '--- Host        : '${SYSTEM};
152  print - '--- modipsl     : '${F_MOD};
153  print - '--- libIGCM     : '${libIGCM};
154  print - '--- basic job   : '${F_JOB};
155  print - '--- basic card  : '${F_RCI};
156 }
157#-
158[[ ${x_v} = 'verbose' ]] && print - "\nInstallation of jobs for '${SYSTEM}'";
159#-
160
161NbErr=0
162
163#-
164# Define Project parameters to set up jobs header for Irene (TGCC)
165# on Irene define ProjectID and ProjectCore : option or answer
166# on Irene ProjectNode default projectnode set to xlarge since 17/10/2018
167#-
168
169
170if [ X"${SYSTEM}" == "Xirene" ] ; then
171
172  #- set ProjectID if required
173  if ( ! ${x_p} ) ; then
174    #- default ProjectID
175    ProjectID=$( ccc_myproject | grep -i irene |grep -i skylake | gawk '{ if ( $3 ~ /^project$/ && $4 !~ /^tgcc/ ) { print $4 } }' | sort -u | grep -v gencmip6 | head -n 1 )
176    ProjectID=${ProjectID:="gch0316"}
177    answer=""
178    print - "Wait for the next question ..."
179    print - "Hit Enter or give project ID (default is ${ProjectID}), possible projects are $( echo $( ccc_myproject | grep -i irene | grep -i skylake | gawk '{ if ( $3 ~ /^project$/ && $4 !~ /^tgcc/ ) { print $4 } }' | grep -v gencmip6 | sort -u ) ) or other xxxcmip6 : $(for i in $(groups) ; do echo $i|grep -v gencmip6|grep .cmip6 1>/dev/null 2>&1 && echo -n $i " " ; done ; echo ) "
180    read answer
181
182    if [ "X${answer}" != "X" ] ; then
183      ProjectID=${answer}
184    fi
185
186  fi # if ( ! ${x_p} )
187
188  echo  ProjectID is ${ProjectID} at Irene
189
190
191  # set ProjectNode if required
192  if ( ! ${x_q} ) ; then 
193     #- default ProjectNode
194     ProjectNode="xlarge"
195     answerOK=false
196 
197     while ( ! ${answerOK} ) ; do
198       answer="" 
199       print - "Hit Enter or give TYPE OF NODE required for post-processing (default is \"${ProjectNode}\"), possible types of nodes are \"skylake\" or \"xlarge\" : " 
200       read answer
201       [ "X${answer}" == "X" ] || [ "X${answer}" == "Xskylake" ] || [ "X${answer}" == "Xxlarge" ] && answerOK=true
202     done
203 
204     if [ "X${answer}" != "X" ] ; then
205       ProjectNode=${answer} 
206     fi
207 
208  fi # if ( ! ${x_q} )
209  echo ProjectNode for post-processing is ${ProjectNode} at Irene
210
211  #- ProjectNode is known (option or answer) set ProjectCoreMax
212  [ "${ProjectNode}" = "xlarge" ] && ProjectCoreMax="112" || ProjectCoreMax="48" 
213  #- ProjectCoreMax is 48 for standard and 112 for xlarge
214
215  if ( ! ${x_c} ) ; then
216    #- ProjectNode is known (option or answer), set ProjectCore default
217    [ "${ProjectNode}" = "xlarge" ] && ProjectCore="8" || ProjectCore="4" 
218
219    # let check minimum/maximum value 1/${ProjectCoreMax}
220
221    answerOK=false
222
223    while ( ! ${answerOK} ) ; do
224      answer=""
225      print - "Hit Enter or give NUMBER OF CORES required for post-processing (default is \"${ProjectCore}\")"
226      print - "possible numbers of cores are \"1\" to \"${ProjectCoreMax}\" for ${ProjectNode} : "
227      read answer
228      [ "X${answer}" == "X" ] || [ ${answer} -ge 1 -a ${answer} -le ${ProjectCoreMax} ] && answerOK=true
229    done
230
231    if [ "X${answer}" != "X" ] ; then
232      ProjectCore=${answer}
233    fi
234
235  fi # if ( ! ${x_c} )
236
237  echo ProjectCore for post-processing is ${ProjectCore}
238  #- ProjectCore is set (option or answer)
239
240  #- ProjetCore is known (option or answer) set PostID : project ID for post-processing
241
242  if ( ! ${x_s} ) ; then
243    #- ProjetCore is known (option or answer) set PostID : project ID for post-processing
244    PostID=$( ccc_myproject | grep -i irene | grep -i ${ProjectNode} | gawk '{ if ( $3 ~ /^project$/ && $4 !~ /^tgcc/ ) { print $4 } }' | sort -u | grep -v gencmip6 | head -n 1 )
245    PostID=${PostID:="${ProjectID}"}
246    answer=""
247    print - "Wait for the next question ..."
248    print - "Hit Enter or give project ID (default is ${PostID}), possible projects are $( echo $( ccc_myproject | grep -i irene | grep -i ${ProjectNode} | gawk '{ if ( $3 ~ /^project$/ && $4 !~ /^tgcc/ ) { print $4 } }' | grep -v gencmip6 | sort -u ) ) or other xxxcmip6 : $(for i in $(groups) ; do echo $i|grep -v gencmip6|grep .cmip6 1>/dev/null 2>&1 && echo -n $i " " ; done ; echo ) "
249    read answer
250
251    if [ "X${answer}" != "X" ] ; then
252      PostID=${answer}
253    fi
254
255  fi # if ( ! ${x_p} )
256
257  echo  PostID is ${PostID} at Irene on ${ProjectNode} for post-processing
258
259elif [ X"${SYSTEM}" == "Xada" ] ; then
260  if ( ! ${x_m} ) ; then
261    MPIEnvironment=IBM
262    # Intel MPI Environment.
263    answerOK=false     
264    while ( ! ${answerOK} ) ; do
265      answer=""
266      print - "Hit Enter or give MPI Environement (default is ${MPIEnvironment}), possible MPI environments are IBM (MPI IBM) and Intel (MPI Intel) :"
267      read answer
268      [ "X${answer}" == "X" ] || [ "X${answer}" == "XIBM" ] || [ "X${answer}" == "XIntel" ] && answerOK=true
269    done
270
271    if [ "X${answer}" != "X" ] ; then
272      MPIEnvironment=${answer}
273    fi
274  fi # if ( ! ${x_pm} )
275  echo MPIEnvironment is ${MPIEnvironment}
276
277elif [ X"${SYSTEM}" == "Xlxiv8" ] || [ X"${SYSTEM}" == "Xifort_CICLAD" ] ; then
278  # obelix, ciclad, climserv
279  echo ""
280  echo "You need to check and maybe adapt headers in the main job especially the line: "
281  echo "  #PBS -l nodes=x:ppn=y "
282  echo "where x is the number of nodes, y the number of cores per node and x*y is the total number of cores for the job. "
283  echo "y must not be bigger than the maximum numer of cores per node on the machine (often 8 or 16)."
284fi # if [ X"${SYSTEM}" == "Xcurie" ]
285
286#-
287# Define the pattern string to substitute
288#-
289W_P='#-Q- '; W_W=${W_P}${SYSTEM};
290#-
291# Extract list of 'config.card' files
292# and create jobs with AA_job
293#-
294F_CFG='config.card';
295F_CFG_ENS='ensemble.card';
296SUBMIT_DIR_ENS=$( pwd )
297for i in $( pwd )/config.card
298do
299  if [ ! -f $i ] ; then
300    echo ""
301    echo "################## WARNING ##################"
302    echo "No config.card available in current directory"
303    echo ""
304    continue
305  fi
306
307
308  j=$(cd ${i%/*};/bin/pwd;)
309  n_f=${F_RCI##*/};
310
311  if [ ! X$( echo ${j} | grep EXPERIMENTS ) = X ] ; then
312    # Do not treat config.card if it is in sub-directory of EXPERIMENTS
313    # Continue to next config.card
314    continue
315  else
316    [[ ${x_v} = 'verbose' ]] && print - "\nWorking with file ${F_CFG}\nin directory ${j}\nfor ${n_f}";
317  fi
318
319  # Find out if new structure and set .resol filename
320  if [ -d ${j}/EXPERIMENTS ] && [ -d ${j}/GENERAL ] ; then
321    # New Structure
322    [[ ${x_v} = 'verbose' ]] && echo "This is new configuration structure"
323    new_struct=yes
324    resolfile=$j/.resol
325  else
326    # Old Structure
327    new_struct=no
328    resolfile=$j/../.resol
329  fi
330
331  # Get all variables declared in section UserChoices in config.card
332  IGCM_card_DefineArrayFromSection ${j}'/'${F_CFG} UserChoices
333  # Set default values
334  config_UserChoices_ExpType=""
335  RESOL_ATM_3D=this_is_a_test_string
336  RESOL=this_is_another_test_string
337  typeset option
338  for option in ${config_UserChoices[*]} ; do
339    IGCM_card_DefineVariableFromOption ${j}'/'${F_CFG} UserChoices ${option}
340  done
341
342  # Find the JobName : JobName might contain the variable RESOL_ATM_3D that will be replaced by what is in .resol file
343  if [ ! X$( echo ${config_UserChoices_JobName} | grep ${RESOL_ATM_3D} ) = X ] ; then
344    TRUERESOL=$( tail -1 $resolfile | awk "-F=" '{print $2}' )
345    echo TRUERESOL = $TRUERESOL
346    JobName=$( echo ${config_UserChoices_JobName} | sed -e "s/${RESOL_ATM_3D}/${TRUERESOL}/" )
347    IGCM_card_WriteOption ${j}'/'${F_CFG} UserChoices JobName ${JobName}
348  elif [ ! X$( echo ${config_UserChoices_JobName} | grep ${RESOL} ) = X ] ; then
349    TRUERESOL=$( head -1 $resolfile  )
350    JobName=$( echo ${config_UserChoices_JobName} | sed -e "s/${RESOL}/${TRUERESOL}/" )
351    IGCM_card_WriteOption ${j}'/'${F_CFG} UserChoices JobName ${JobName}
352  else
353    JobName=${config_UserChoices_JobName}
354  fi
355
356  # Check JobName validity : only alphanumerical characters, "-" and "." are authorized
357  ins_job_Check_JobName
358  RetCode=$?
359  [[ $RetCode -gt 0 ]] && continue
360
361  [[ ${x_v} = 'verbose' ]] && echo "JobName=${JobName}"
362
363  # Add specific treatment for new type of directory structure
364  if [ ${new_struct} == yes ] ; then
365
366    if [ "X${config_UserChoices_ExpType}" = X ] ; then
367      echo "\nERROR in ${j}/config.card"
368      echo "ins_job stops here"
369      echo "=> The variable ExpType must be added in config.card in section UserChoices"
370      echo "=> ExpType gives the directory for the .card configuration files for the wanted experiement. For exemple ExpType=IPSLCM5/historical"
371      exit 4
372    else
373      [[ ${x_v} = 'verbose' ]] && echo "ExpType= ${config_UserChoices_ExpType}"
374    fi
375
376    if [ -d ${j}/${JobName} ] ; then
377      echo "Directory ${j}/${JobName} exists already. It will not be overwritten."
378      echo "Remove the existing directory or change JobName before relaunching ins_job."
379      continue
380    fi
381    echo "=> Submit directory ${JobName} will be created with cards from EXPERIMENTS/${config_UserChoices_ExpType}"
382    cp -r ${j}/EXPERIMENTS/${config_UserChoices_ExpType} ${j}/${JobName}
383    cp -r ${j}/GENERAL/* ${j}/${JobName}/.
384    cp -f ${j}/${F_CFG}  ${j}/${JobName}/.
385    if [ -f ${F_CFG_ENS} ] ; then
386      cp -f ${j}/${F_CFG_ENS}  ${j}/${JobName}/.
387      SUBMIT_DIR_ENS=${j}/${JobName}
388    fi
389    rm -f ${j}/${F_CFG}
390    rm -f ${j}/${F_CFG_ENS}
391    rm -f ${j}/${F_CFG}.bak
392    j=${j}/${JobName}
393    [[ ${x_v} = 'verbose' ]] && echo new j=$j
394  fi
395  # end specific treatment for new type directory structure
396
397  [[ -f ${j}'/'${n_f} ]] && { ins_job_Warning; } || \
398   {
399    [[ ${x_v} = 'verbose' ]] && print - "\nCopying file ${F_RCI}\nin directory ${j}";
400    \cp ${F_RCI} ${j};
401   }
402
403  #==================================
404  # Read ListOfComponents section:
405  #echo
406  #IGCM_debug_Print 1 "DefineArrayFromSection : ListOfComponents"
407
408  IGCM_card_DefineArrayFromSection  ${j}'/'${F_CFG} ListOfComponents
409  for comp in ${config_ListOfComponents[*]} ; do
410    IGCM_card_DefineArrayFromOption  ${j}'/'${F_CFG} ListOfComponents ${comp}
411  done
412  #IGCM_debug_Print 3 ${config_ListOfComponents[*]}
413
414  #==================================
415  # Read Executable section:
416  IGCM_card_DefineArrayFromSection ${j}'/'${F_CFG} Executable
417
418  # Define the execution context (MPMD, SPMD, MPI/OMP ...)
419  IGCM_config_ConfigureExecution ${j}'/'${F_CFG}
420
421  # coreNumber    : TOTAL NUMBER OF CORES
422  # mpiTasks      : TOTAL NUMBER OF MPI TASKS
423  # openMPthreads : NUMBER OF OpenMP THREADS
424
425  # File name for Job
426  n_f='Job_'${JobName};
427  [[ ${x_f} = 'false' ]] && [[ -f ${j}'/'${n_f} ]] && { ins_job_Warning; continue; }
428  [[ ${x_v} = 'verbose' ]] && print - "\nWorking with file ${F_CFG}\nin directory ${j}\nfor ${n_f}";
429  sed -e "/^${W_W} */ s///" \
430      -e "/^${W_P}/d"       \
431      -e "s%::modipsl::%${F_MOD}%" \
432      -e "s/::Jobname::/${JobName}/" \
433      -e "s/::default_project::/${ProjectID}/" \
434      ${F_JOB} > ${j}'/'${n_f}
435  chmod u+x ${j}'/'${n_f}
436
437  # update Headers so that ressources description are accurate (MPMD/SPMD/...)
438  IGCM_sys_updateHeaders ${j}'/'${n_f}
439done
440
441#-
442# Extract list of AA_* files in libIGCM
443# and create jobs (for all except AA_job)
444#-
445for i in $(find ${libIGCM} -maxdepth 1 -name "AA_*" -print)
446do
447  i_f=${i##*/};
448  [[ ${i_f} = 'AA_job' ]] && { continue; }
449  j=${i%/*}; n_f=${i_f#AA_}'.job';
450  [[ ${x_f} = 'false' ]] && [[ -f ${j}'/'${n_f} ]] && { ins_job_Warning; continue; }
451  [[ ${x_v} = 'verbose' ]] && print - "\nIn directory ${j}\n${i_f} -> ${n_f}"
452  sed -e "/^${W_W} */ s///" \
453      -e "s%::modipsl::%${F_MOD}%" \
454      -e "/^${W_P}/d"       \
455      -e "s/::default_node::/${ProjectNode}/" \
456      -e "s/::default_core::/${ProjectCore}/" \
457      -e "s/::default_project::/${ProjectID}/" \
458      -e "s/::default_post_project::/${PostID}/" \
459      ${i} > ${j}'/'${n_f}
460  chmod u+x ${j}'/'${n_f}
461done
462#-
463# set default_project in libIGCM_sys_curie.ksh too.
464#-
465if [ X"${SYSTEM}" == "Xcurie" ] ; then
466  i=${libIGCM}/libIGCM_sys/libIGCM_sys_curie.ksh
467  sed -i -e "s/::default_project::/${ProjectID}/" ${i}
468fi
469#-
470# Limited to hindcast/forecast and date restart Ensemble for the time being
471if [ ${x_e} = 'true' ] ; then
472  #.. Read input data from ensemble.card ..
473  SUBMIT_DIR=${SUBMIT_DIR_ENS}
474  RUN_DIR="${WORKDIR}/ENSEMBLE_TMP"
475  #
476  # Copy initial things around and define variables (hindcast/forecast case)
477  IGCM_sys_Cd ${SUBMIT_DIR}
478  IGCM_ensemble_Init
479
480  if [[ ${ensemble_Ens_PARAMETRIC_active} = 'y' ]] ; then
481    echo "WARNING: Parametric Ensemble is not implemented yet..."
482  fi
483
484  if [[ ${ensemble_Ens_DATE_active} = 'y' ]] ; then
485    IGCM_sys_Cd ${SUBMIT_DIR}
486    IGCM_ensemble_DateInit
487    # As it says
488    IGCM_sys_Cd ${SUBMIT_DIR}
489    IGCM_ensemble_DatePeriodicStarts
490    # As it says
491    IGCM_sys_Cd ${SUBMIT_DIR}
492    IGCM_ensemble_DateNonPeriodicStarts
493    # Clean
494    IGCM_sys_Rm -rf ${RUN_DIR}
495  fi
496
497  if [[ ${ensemble_Ens_PERTURB_active} = 'y' ]] ; then
498    IGCM_sys_Cd ${SUBMIT_DIR}
499    IGCM_ensemble_CastInit
500    # As it says
501    IGCM_sys_Cd ${SUBMIT_DIR}
502    IGCM_ensemble_CastPeriodicStarts
503    # As it says
504    IGCM_sys_Cd ${SUBMIT_DIR}
505    IGCM_ensemble_CastNonPeriodicStarts
506    # As it says
507    IGCM_sys_Cd ${SUBMIT_DIR}
508    IGCM_ensemble_CastMemberList
509    # Done
510    #IGCM_sys_Cp ${RUN_DIR}/CreatedDir.txt ${SUBMIT_DIR}
511    IGCM_sys_Cd ${SUBMIT_DIR}
512    # Clean
513    IGCM_sys_Rm -rf ${RUN_DIR}
514  fi
515fi
516#-
517[[ ${x_v} = 'verbose' ]] && print - "";
518#-
519# That's all folks
520#-
521
522if [ ${NbErr} -ne 0 ] ; then
523  echo "################ ERROR ################"
524  echo "${NbErr} invalid JobName(s) found, check the log"
525fi
526
527
528exit 0;
Note: See TracBrowser for help on using the repository browser.