source: trunk/libIGCM/ins_job @ 1465

Last change on this file since 1465 was 1465, checked in by acosce, 6 years ago

Add the choice by ins_job of number of cores for pack_output.
I don't modify the number of cores of pack_restart and pack_debug that actually well run on 4 cores.

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