#!/bin/sh
#
# Conv-host for IBM SP:
#  Translates +pN-style charmrun options into 
# POE (Parallel Operating Environment) options.

args=""
pes=1

while [ $# -gt 0 ]
  do
  case $1 in
      +p)
	  pes=$2
	  shift
	  ;;
      +ppn)
	  args=$args"$1 $2"
	  ppnused="$2"
	  shift
	  ;;
      +p[0-9]*)
          pes=`expr substr $1 3 10`
          ;;
      +ln)
	  logical=$2
	  shift
	  ;;
      +ns)
	  nodesize=$2
	  shift
	  ;;
      +ll)
	  llfile=$2
	  shift
	  ;;
      *)
	  args=$args"$1 "
	  ;;
  esac
  shift
done

if [ -n "$args" ]
    then
    args1=`expr substr "$args" 1 1`
fi

if [ -z "$args" -o "$args1" == "-" -o "$args1" == "+" ]
    then
    # print usage help
    echo "help"
    exit
fi

executable=`echo $args | awk '{print $1}'`

# check if the node size has been set, or a file called .nodesize is present
#if [ -z "$nodesize" ]
#    then
#    if [ -f ".nodesize" ]
#	then
#	nodesize=`cat .nodesize`
#    elif [ -f "$HOME/.nodesize" ]
#	then
#	nodesize=`cat $HOME/.nodesize`
#    fi
#fi

# check that nodesize is a real number
#if [ -n "$nodesize" -a "$nodesize" -gt 0 ]
#    then
#    echo
#    else
#    echo
#    echo "No node size specified. Either use flag \"+ns <size>\" or create a file called"
#    echo "\".nodesize\" in the current directory on in your home directory."
#    echo
#    exit
#fi

# check if the load leveler template file has been set or a file called charmrun.ll is present
if [ -z "$llfile" ]
    then
    if [ -f "charmrun.ll" ]
	then
	llfile="charmrun.ll"
    elif [ -f "$HOME/charmrun.ll" ]
	then
	llfile="$HOME/charmrun.ll"
    fi
fi

if [ -z "$llfile" ]
    then
    echo "No load leveler template specified. Either use the flag \"+ll <llfile>\" or create"
    echo "a file called \"charmrun.ll\" in the current directory on in your home directory."
    echo
    exit
fi

filename="charmrun_script.$$.ll"
interactive=`grep queue $llfile|wc -l`

if [ $interactive -gt 1 ]
    then
    echo "Multiple queueing not supported!"
fi

if [ $interactive -eq 0 ]
    then
    node_usage="shared"
else
    node_usage="not_shared"
fi

if [ -n "$ppnused" ]
    then
    total_tasks=`expr $pes / $ppnused`
    if [ $pes -ne `expr $total_tasks \* $ppnused` ]
	then
	echo
	echo "number of processors must be a multiple of number of processors per node!"
	echo
	exit
    fi
    tasks_per_node=1
    if [ -n "$logical" ]
	then
	tasks_per_node=$logical
    fi
    if [ -n "$nodesize" ]
	then
	tasks_per_node=`expr $nodesize / $ppnused`
    fi
    if [ -n "$logical" -a -n "$nodesize" ]
	then if [ $logical -ne $tasks_per_node ]
	    then
	    echo
	    echo "Both +ln and +ns used, but they do not meet the rule <+ln> = <+ns> / <+ppn>"
	    echo
	    exit
	fi
    fi
    tasks_per_node="#@ tasks_per_node = "$tasks_per_node
else
    total_tasks=$pes
fi

cat > $filename <<EOF
# System settings
#@ node_usage = $node_usage
#@ network.LAPI = csss,,US
#@ total_tasks = $total_tasks
$tasks_per_node

# User settings
EOF

grep -E -v "node|network|tasks|queue" $llfile | grep -E "#@"  >> $filename

cat >> $filename <<EOF

# Default Settings
EOF
present=`grep job_type $llfile|wc -l`
if [ $present -eq 0 ]
    then
    cat >> $filename <<EOF
#@ job_type = parallel
EOF
fi

present=`grep job_name $llfile|wc -l`
if [ $present -eq 0 ]
    then
    cat >> $filename <<EOF
#@ job_name = charmrun_$executable.$$
EOF
fi

present=`grep wall_clock_limit $llfile|wc -l`
if [ $present -eq 0 ]
    then
    cat >> $filename <<EOF
#@ wall_clock_limit = 0:10:00
EOF
fi

present=`grep notification $llfile|wc -l`
if [ $present -eq 0 ]
    then
    cat >> $filename <<EOF
#@ notification = never
EOF
fi

if [ $interactive -ne 0 ]
    then
    present=`grep output $llfile|wc -l`
    if [ $present -eq 0 ]
	then
	cat >> $filename <<EOF
#@ output = output_$executable.$$
EOF
    fi

    present=`grep error $llfile|wc -l`
    if [ $present -eq 0 ]
    then
	cat >> $filename <<EOF
#@ error = error_$executable.$$
EOF
    fi
fi
 
cat >> $filename <<EOF
#@ queue

# System defined exports
MP_MSG_API=lapi
LAPI_USE_SHM=yes
MP_INTRDELAY=100
MP_EAGER_LIMIT=65536
MP_SHARED_MEMORY=yes
MP_USE_BULK_XFER=yes
MEMORY_AFFINITY=MCM
MP_TASK_AFFINITY=MCM
MP_EUILIB=us

# User defined exports
EOF

# user exports
grep -E -v "#@" $llfile | grep "export" >> $filename

if [ ! -x "$PWD/$executable" ]
    then
    echo "Executable not found: $PWD/$executable"
    exit
fi

if [ $interactive -eq 0 ]
    then
    # submit the job as poe, iterating 
    echo "Running interactively> poe $PWD/$args -llfile $filename"
    poe $PWD/$args -llfile $filename
    status=$?
    if [ $status -eq 255 ];
      then
      llstatus=1
    else
      llstatus=0
    fi
    until (exit $llstatus);
      do
      echo "Retrying in two minutes..."
      sleep 120
      poe $PWD/$args -llfile $filename;
      status=$?
      if [ $status -eq 255 ];
        then
        llstatus=1
      else
        llstatus=0
      fi
    done
    if [ $status -ne 0 ];then exit $status;fi
    
else
    # append the command at the end of the file and llsubmit it
    echo "Submitting batch> poe $PWD/$args"
    cat >> $filename <<EOF

poe $PWD/$args
EOF
    llsubmit $filename
fi

rm $filename
