#! /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