#! /bin/sh -f # # This script builds a shell job script which is supplied as input # to the GRD qsub command. The script is built based on information # obtained from a file passed as the script's argument. This file # contains a list of environment variables which are set by way # of "sourcing" the file from this script. The evironment variables # set as a result of this action are then used to characterize the # user's job request. Once the job script has been submitted the # GRD job id is appended to the file passed as an argument to this # script to be used by other scripts at a later time. # The temporary job script is created for the submission and then removed # at the end of this script. . ${GLOBUS_LOCATION}/libexec/globus-script-initializer globus_source ${libexecdir}/globus-gram-protocol-constants.sh globus_source ${libexecdir}/globus-sh-tools.sh globus_source ${libexecdir}/globus-gram-job-manager-tools.sh qsub=${GLOBUS_GRAM_JOB_MANAGER_QSUB-qsub} qselect=${GLOBUS_GRAM_JOB_MANAGER_QSELECT-qselect} awk=${GLOBUS_SH_AWK-awk} sed=${GLOBUS_SH_SED-sed} # # Mod mpirun to use the wrapper script for Sun MPI jobs # (See grd_pe section) mpirun=${GLOBUS_GRAM_JOB_MANAGER_MPIRUN-mpirun} rm=${GLOBUS_SH_RM-rm} expr=${GLOBUS_SH_EXPR-expr} test=${GLOBUS_SH_TEST-test} SH=${GLOBUS_SH-/bin/sh} # File name to be used for temporary job script GRD_JOB_SCRIPT="${local_tmpdir}/grd_job_script."$$ arg_file=$1 # Check for the argument file. If it does not exist # then return with an error immediately if [ ! -f $arg_file ] ; then echo GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_PROTCOL_ERROR_BAD_SCRIPT_ARG_FILE exit 1 fi # Source the argument file to set environment variables # defining all the job arguments . $arg_file # If a logfile name has been defined then activate debug mode if [ $grami_logfile = "/dev/null" ] ; then DEBUG_ECHO=: else DEBUG_ECHO=echo fi $DEBUG_ECHO "JM_SCRIPT: in grd_submit">> $grami_logfile $DEBUG_ECHO "" >> $grami_logfile $DEBUG_ECHO ============================================ >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: ====argument file contents====" >> $grami_logfile if [ "$DEBUG_ECHO" = "echo" ] ; then cat $arg_file >> $grami_logfile fi $DEBUG_ECHO "JM_SCRIPT: ====argument file contents====" >> $grami_logfile $DEBUG_ECHO "" >> $grami_logfile #assumption is that the qsub path will take the form # //...//bin//qsub # so parse the command from the end to get the GRD ROOT dir. # # from the qsub path, remove the last slash and all that follows it. # Leaving the directory. Not all systems have dirname. grd_dir=`echo $qsub | $sed 's|/[^/][^/]*$||'` # remove everything up to the last slash. Leaving the grd arch value. grd_arch=`echo $grd_dir | $sed 's|.*/||'` #remove the next 2 subdir (e.g. /) leaving the grd_root grd_dir=`echo $grd_dir | $sed 's|/[^/][^/]*$||'` GRD_ROOT=`echo $grd_dir | $sed 's|/[^/][^/]*$||'` . $GRD_ROOT/default/common/settings.sh # The following several lines of code can be used to perform 2 # additional error checks prior to job submission. The first check is # for the existance of the directory which the user requested # be the working directory. If it does not exist the script # returns an error and the job is not submitted. The second check # is for existance of the file requested by the user to be used for # stdin. If the file does not exist the scripts returns an error and # the job is not submitted. # These checks are only valid if performed on the file system to be used # by the host on which the job will run. But, this file system may not # be shared with host from which the job is submitted. Therefore, the # check does not make sense. If however the host from which the job # will be submitted (i.e. the host running the globus gatekeeper) # shares file systems with all the hosts which may potentially # run the job these checks can be used. In order to have the job # manager perform these checks the following 2 sections of code # should *not* be commented out. # Check for existance of directory #$DEBUG_ECHO "JM_SCRIPT: testing for existance of directory $grami_directory" >> $grami_logfile #if [ -d $grami_directory ]; then # $DEBUG_ECHO "JM_SCRIPT: directory $grami_directory found" >> $grami_logfile # cd $grami_directory #else # $DEBUG_ECHO "JM_SCRIPT: directory $grami_directory DOES NOT exist; exiting with exit code 1" >> $grami_logfile # echo GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_PROTCOL_ERROR_BAD_DIRECTORY # exit 1 #fi # # Check for existance of stdin file if not /dev/null # #if [ $grami_stdin != "/dev/null" ]; then # $DEBUG_ECHO "JM_SCRIPT: testing for existance of stdin file $grami_stdin" >> $grami_logfile # if [ -r $grami_stdin ]; then # $DEBUG_ECHO "JM_SCRIPT: stdin file $grami_stdin found and is readable" >> $grami_logfile # else # $DEBUG_ECHO "JM_SCRIPT: stdin file $grami_stdin DOES NOT exist or is not readable; exiting with exit code 1" >> $grami_logfile # echo GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_PROTCOL_ERROR_STDIN_NOT_FOUND # exit 1 # fi #fi # Check for non supported parameters here. That is, if any of the RSL # parameters which GRD can not support have been requested return an error. # Currently all RSL attributes are supported by GRD # if (unsupported parameters found) # $DEBUG_ECHO "JM_SCRIPT: unsupported parameters found. Exiting with error." >> $grami_logfile # else # $DEBUG_ECHO "JM_SCRIPT: No unsupported parameters found" \ # >> $grami_logfile # fi # $DEBUG_ECHO "JM_SCRIPT: testing for unsupported parameters" >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: No unsupported parameters found" >> $grami_logfile # Verify existance of queue if queue parameter is not NULL $DEBUG_ECHO "JM_SCRIPT: testing for queue attribute specification" \ >> $grami_logfile if [ ! -z "${grami_queue}" ]; then $DEBUG_ECHO "JM_SCRIPT: testing for existance of GRD queue $grami_queue" \ >> $grami_logfile status=`$qselect -q $grami_queue` if ($test "$?" -eq "0") then $DEBUG_ECHO "JM_SCRIPT: GRD queue $grami_queue found" >> $grami_logfile else $DEBUG_ECHO "GRD queue [$grami_queue] DOES NOT exist" >> $grami_logfile $DEBUG_ECHO "exiting with exit code 1" >> $grami_logfile echo GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_PROTCOL_ERROR_INVALID_QUEUE exit 1 fi else $DEBUG_ECHO "JM_SCRIPT: no queue attribute specified" >> $grami_logfile fi # 4 jobtypes exist GRD result # ----------------- ------------------ # jobtype 0 = mpi -----> run mpirun # jobtype 1 = single -----> submit one copy of grd script (if grami_count = 1) # jobtype 1 = jobarray -----> submit jobarray (if grami_count != 1) # jobtype 2 = multiple -----> submit count copy(s) of grd script # jobtype 3 = condor -----> ERROR # # Modified by Yoshio Tanaka for jobarray submission. # if ((jobtype == single) && (count == 1)) then (jobtype = single) # if ((jobtype == single) && (count != 1)) then (jobtype = jobarray) # $DEBUG_ECHO "JM_SCRIPT: testing jobtype" >> $grami_logfile if [ $grami_job_type = "0" ] ; then grd_jobtype="mpi" elif [ $grami_job_type = "1" ] ; then if [ $grami_count = "1" ] ; then grd_jobtype="single" else grd_jobtype="jobarray" fi elif [ $grami_job_type = "2" ] ; then grd_jobtype="multiple" elif [ $grami_job_type = "3" ] ; then $DEBUG_ECHO "JM_SCRIPT: ERROR: jobtype parameter not supported" >> $grami_logfile echo "GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_CLIENT_ERROR_JOBTYPE_NOT_SUPPORTED" exit 1 else $DEBUG_ECHO "JM_SCRIPT: invalid jobtype parameter" >> $grami_logfile echo GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_CLIENT_ERROR_INVALID_JOBTYPE exit 1 fi # end of modification # Determining cpu time limit $DEBUG_ECHO "JM_SCRIPT: testing for cpu time limit" >> $grami_logfile if [ $grami_max_time -eq 0 ] ; then cpu_time=0 $DEBUG_ECHO "JM_SCRIPT: No cpu time specified, using [unlimitd] cpu time" \ >> $grami_logfile else cpu_time="$grami_max_time" $DEBUG_ECHO "JM_SCRIPT: using $cpu_time minutes for max cpu time" \ >> $grami_logfile fi # Determining memory limit # min memory is *NOT* supported # Globus default RSL attribute memory units are in Mbytes # GRD default memory attribute units are in Kbytes... # so a conversion from Mbytes to Kbytes must be made Kb=1024 $DEBUG_ECHO "JM_SCRIPT: testing for maximum memory limit" >> $grami_logfile if [ $grami_max_memory -eq 0 ] ; then max_memory=0 $DEBUG_ECHO "JM_SCRIPT: no maximum memory requested specified" \ >> $grami_logfile else max_memory=`$expr "$grami_max_memory" \* "$Kb"` $DEBUG_ECHO "JM_SCRIPT: requested $grami_max_memory Mb for max memory" \ >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: converting Mb to GRD default unit of Kb" \ >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: using $max_memory Kb for maximum memory" \ >> $grami_logfile fi $DEBUG_ECHO "JM_SCRIPT: testing for minimum memory limit" >> $grami_logfile if [ $grami_min_memory -eq 0 ] ; then $DEBUG_ECHO "JM_SCRIPT: no minimum memory requested specified" \ >> $grami_logfile else $DEBUG_ECHO "JM_SCRIPT: requested $grami_min_memory Mb for min memory" \ >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: minimum memory request is not supported" \ >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: minimum memory request is being ignored" \ >> $grami_logfile fi # Start building job script $DEBUG_ECHO "JM_SCRIPT: starting to build GRD job script" >> $grami_logfile echo "#!${SH}" >> $GRD_JOB_SCRIPT echo "# GRD batch job script built by Globus job manager" >> $GRD_JOB_SCRIPT echo "" >> $GRD_JOB_SCRIPT echo "" >> $GRD_JOB_SCRIPT echo "#$ -S ${SH}" >> $GRD_JOB_SCRIPT if [ ! -z "${grami_queue}" ] ; then echo "#$ -q $grami_queue" >> $GRD_JOB_SCRIPT fi if [ ! -z "${grami_project}" ] ; then echo "#$ -P $grami_project" >> $GRD_JOB_SCRIPT fi if [ $cpu_time -ne 0 ] ; then echo "#$ -l h_cpu=$cpu_time" >> $GRD_JOB_SCRIPT fi if [ $max_memory -ne 0 ] ; then echo "#$ -l h_data=$max_memory" >> $GRD_JOB_SCRIPT fi # NOTE: stdin supported below by redirection # echo "#$ -i $grami_stdin" >> $GRD_JOB_SCRIPT echo "#$ -o $grami_stdout" >> $GRD_JOB_SCRIPT echo "#$ -e $grami_stderr" >> $GRD_JOB_SCRIPT # Below is a while loop to reformat the environment variable # string to the format needed for the GRD job script. The environment # variables for the GRD job will be set during the execution # of the job script. The loop obtains environment variable information # from the variable $grami_env. The information is then written # to the GRD job script one line per variable in the form: # env_variable=env_value; export env_variable # where... # env_variable is the name of the environment variable # env_value is the value of the environment variable $DEBUG_ECHO "JM_SCRIPT: checking environment" >> $grami_logfile # #loop through all the environment variables. Variables and values are seperate #arguments. While assembling var/value pairs add the specific syntax #required for this scheduling system. # new_grami_env="" # # Modified by Yoshio Tanaka for jobarray submission # environment variables GRD_JOBARRAY_BASE and GRD_JOBARRAY_STRIDE # are retrieved into local variables # grd_pe= grd_cre= grd_jobarray_base= grd_jobarray_stride=1 if [ ! -z "${grami_env}" ] ; then eval set -- ${grami_env} x=0 while [ "$#" -ne 0 ]; do if [ $x = 0 ] ; then save_variable=$1 x=1 else x=0 echo "${save_variable}=$1; export ${save_variable}" >> $GRD_JOB_SCRIPT case ${save_variable} in GRD_PE) grd_pe=$1;; GRD_CRE) grd_cre=$1;; GRD_JOBARRAY_BASE) grd_jobarray_base=$1;; GRD_JOBARRAY_STRIDE) grd_jobarray_stride=$1;; *) ;; esac fi shift done fi # end of modification $DEBUG_ECHO "JM_SCRIPT: done checking environment" >> $grami_logfile # # Added by Yoshio Tanaka for jobarray submission # count represents the number of elements of jobarray # environment variables GRD_JOBARRAY_BASE and GRD_JOBARRAY_STRIDE # if [ $grd_jobtype = "jobarray" ] ; then if [ -z "$grd_jobarray_base" ] ; then echo "#$ -t $grami_count" >> $GRD_JOB_SCRIPT else grd_jobarray_margin=`expr $grami_count - 1` grd_jobarray_last=`expr "$grd_jobarray_base" + "$grd_jobarray_margin" \* "$grd_jobarray_stride"` echo "#$ -t $grd_jobarray_base:$grd_jobarray_last:$grd_jobarray_stride" >> $GRD_JOB_SCRIPT fi fi # end of addition new_grami_args="" if [ ! -z "${grami_args}" ] ; then eval set -- ${grami_args} new_grami_args="$*" fi $DEBUG_ECHO "JM_SCRIPT: done setting new_grami_args" >> $grami_logfile # handle CPU count here because we need an env var if [ -n "$grd_pe" ] ; then echo "#$ -pe $grd_pe $grami_count" >> $GRD_JOB_SCRIPT # # Add SGE + HPC ClusterTools loose integration environments # # define mpirun for Sun HPC ClusterTools mprun wrapper mpirun=${GRD_ROOT}/mpi/sunhpc/loose-integration/MPRUN # assume the CRE exclusive complex to be "cre" echo "#$ -l $grd_cre" >> $GRD_JOB_SCRIPT # inherit the runtime environment echo "#$ -V" >> $GRD_JOB_SCRIPT # change to the current working directory echo "#$ -cwd" >> $GRD_JOB_SCRIPT fi #else # $DEBUG_ECHO "JM_SCRIPT: ERROR: User must set GRD_PE env var to use count" # >> $grami_logfile # echo "GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_PROTCOL_ERROR_JOBTYPE_NOT_SUPPORTED" # exit 1 #fi # Set up GRD environment $DEBUG_ECHO "JM_SCRIPT: before settings.sh" >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: PATH=$PATH" >> $grami_logfile echo ". $GRD_ROOT/default/common/settings.sh" >> $GRD_JOB_SCRIPT $DEBUG_ECHO "JM_SCRIPT: after settings.sh" >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: PATH=$PATH" >> $grami_logfile # Determine directory to be used as working directory echo "# Changing to directory as requested by user" >> $GRD_JOB_SCRIPT echo "cd $grami_directory" >> $GRD_JOB_SCRIPT # Determining job request type echo "# Executing job as requested by user" >> $GRD_JOB_SCRIPT if [ $grd_jobtype = "mpi" ] ; then echo "${mpirun} -np $grami_count $grami_program $new_grami_args" \ >> $GRD_JOB_SCRIPT elif [ $grd_jobtype = "multiple" ] ; then counter=0 while ($test "$counter" -lt "$grami_count") do $DEBUG_ECHO "JM_SCRIPT: in loop counter is $counter " >> $grami_logfile echo "$grami_program $new_grami_args < ${grami_stdin} &" \ >> $GRD_JOB_SCRIPT counter=`$expr $counter + 1` done echo "wait" >> $GRD_JOB_SCRIPT; else echo "$grami_program $new_grami_args < ${grami_stdin}" >> $GRD_JOB_SCRIPT fi $DEBUG_ECHO "JM_SCRIPT: GRD job script successfully built" >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: submitting GRD job script" >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: GRD_JOB_SCRIPT is $GRD_JOB_SCRIPT" >> $grami_logfile # Execute qsub command $DEBUG_ECHO "JM_SCRIPT: ${qsub} $GRD_JOB_SCRIPT" >> $grami_logfile status=`${qsub} $GRD_JOB_SCRIPT` cc=$? $DEBUG_ECHO "JM_SCRIPT: cc=$cc" >> $grami_logfile if ($test "$cc" -eq "0") then job_id=`echo $status | ${awk} '{print $3}'` echo "grami_job_id=${job_id}" >> $arg_file $DEBUG_ECHO "JM_SCRIPT: job $job_id submitted successfully!" \ >> $grami_logfile $DEBUG_ECHO "JM_SCRIPT: returning job state: $GLOBUS_GRAM_PROTCOL_JOB_STATE_PENDING" >> $grami_logfile echo "GRAM_SCRIPT_JOB_ID:$job_id" echo "GRAM_SCRIPT_SUCCESS:$GLOBUS_GRAM_PROTCOL_JOB_STATE_PENDING" else $DEBUG_ECHO "JM_SCRIPT: job *NOT* submitted successfully!" >> $grami_logfile echo "GRAM_SCRIPT_ERROR:$GLOBUS_GRAM_PROTCOL_ERROR_JOB_EXECUTION_FAILED" $DEBUG_ECHO "JM_SCRIPT: status=$status" >> $grami_logfile fi # Remove temporary job script file ${rm} $GRD_JOB_SCRIPT $DEBUG_ECHO "JM_SCRIPT: exiting gram_script_grd_submit" >> $grami_logfile $DEBUG_ECHO "" $DEBUG_ECHO "" exit