#!/bin/sh
#or try
##!/bin/ksh
#
# LINNOX
# ------
#
# Copyright 1999
# Author : D. Zundel
# Shell-Script to convert a File with input-parameters for LINSOL
# in a format that can be used by LINSOL

usage()
{
    echo "usage: $0 [-b] [-c <jobclass>{/sw|/sn}]"            1>&2
    echo "\t[-T <time limit>] [-M <mem limit>] [-p <procs>]"  1>&2
    echo "\t[-n <nodes>] [-f <hostfile>] [-d] <paramfile>" 1>&2
    exit 1
}

die()
{
    echo $1 1>&2
    exit 2
}

stripprefix()
{
    echo $1 | sed -e s'/^LINSOL_//'
}

notnull()
{
    eval VAL=\$$1
    if [ "x$VAL" = "x" ]
    then
	die "ERROR: `stripprefix $1` not specified."
    fi
}

notnullmsg()
{
    if [ "x$2" = "x" ]
    then
	die "ERROR: $1"
    fi
}

checkdir()
{
    if [ ! -d $1 ]
    then
	die "ERROR: Directory $1 does not exist."
    fi
}

checkfile()
{
    if [ ! -r $1 ]
    then
	die "ERROR: File $1 does not exist."
    fi
}

defaultto()
{
    eval VAL=\$$1
    if [ "x$VAL" = "x" ]
    then
	echo "WARNING: `stripprefix $1` not specified." 1>&2
	echo "         Using default ($2)."   1>&2
	eval $1=$2
    fi
}

# Return full path name for the first argument
mydirname()
{
    (cd `echo $1 | sed -e s'/[^\/]*$//' -e's/\/$//' -e's/^$/./'` ; pwd)
}

echo " ***  LINNOX --- LINNOX --- LINNOX                 ***"
echo " ***  is a UNIX wrapper for LINSOL checking the    ***"
echo " ***  parameter file created by the user and       ***"
echo " ***  creating a new parameter file used by LINSOL ***"
echo " ***  Starting parameter-check ....                ***"

# process optional arguments
# Warning: this is mostly a dummy parsing for the options of linsh.
# The interface of linsh and the code below MUST match!

LINSOL_NPROC=1

while getopts :bc:dp:n:T:M:f: option
do
    case $option in
	p)  LINSOL_NPROC=$OPTARG
	    ;;
	f)  LINSOL_HOSTFILE=$OPTARG
	    ;;
	n|b|d|c|T|M)
	    ;;
	*)
	    echo "ERROR: unknown option $OPTARG" 1>&2
	    usage
	    ;;
    esac
done

# We do not shift as we have to pass on all arguments later on
#shift $(( $OPTIND - 1 ))

# first check for mandatory argument
if [ $OPTIND -ne $# ]
then
    echo "ERROR: Specify exactly one parameter file name " 1>&2
    usage
fi


# init filenames

# Use the last argument as the parameter file
eval "PARAMETER_FILE=\${$#}"
# the directory with the executables is chosen automatically
LINSOL_EXE_DIR=`which linsol    2> /dev/null || \
		which plinsol   2> /dev/null || \
		which linsoldb  2> /dev/null || \
		which plinsoldb 2> /dev/null`
LINSOL_EXE_DIR=`mydirname $LINSOL_EXE_DIR`
# else you have to set the directory explicitly!
#LINSOL_EXE_DIR=/??????/?????/????/
LINNOX_EXE_DIR=`mydirname $0`
LINSOL_FILES_DIR=`mydirname $PARAMETER_FILE`
#echo $LINSOL_FILES_DIR
export LINSOL_EXE_DIR LINSOL_FILES_DIR LINNOX_EXE_DIR
if [ $LINSOL_EXE_DIR != $LINNOX_EXE_DIR ]
then
    echo "WARNING: Using executable in directory $LINSOL_EXE_DIR !"
fi

# default directory for files
DEFAULT_DIRECTORY=$LINSOL_FILES_DIR

# Check for hostfile
if [ "x$LINSOL_HOSTFILE" != "x" ] && [ ! -r $LINSOL_HOSTFILE ]
then
    echo "Error: Hostfile $LINSOL_HOSTFILE does not exist or is not readable" 1>&2
    usage
fi

# Check for parameter file
if [ ! -r $PARAMETER_FILE ]
then
    echo "ERROR: Parameter file $PARAMETER_FILE does not exist or is not readable" 1>&2
    usage
fi

# Save parameters for linsh invocation
cmdline="$*"

# init default-parameters
DEFAULT_SOLUTIONS_FILENAME=solution
DEFAULT_MATRIX_DISTRIBUTED=0
DEFAULT_MATRIX_OUTPUT_FORMAT=0
DEFAULT_OUTPUT_DEVICE=6
DEFAULT_INITGUESS=0
DEFAULT_METHOD=10
DEFAULT_ITERATION_MAXIMUM=10000
LINSOL_MAX_ITMAX=10000000
DEFAULT_PRECONDITIONING_METHOD=0
DEFAULT_NORMALIZATION_METHOD=1
DEFAULT_CHECK_SYSTEM=0
DEFAULT_VERBOSE_LEVEL=100
DEFAULT_MATRIX_NORMALIZED=0
DEFAULT_SMOOTHED=1
DEFAULT_MISC=0000
DEFAULT_OPTIMIZE=0000
DEFAULT_THRESHOLD=1.d-5
DEFAULT_MEMORY_FACTOR=0.d0
DEFAULT_RUNTIME_ACCELERATION=0
DEFAULT_BANDW_ALG=1

# Remove all comments and blank lines and massage all assignments
# into good shape for subsequent sourcing
TMPFILE="/tmp/linnox$$"
awk -F= '$0 !~ /^#|^[ \t]*$/ {print toupper($1),$2;}' \
  < $PARAMETER_FILE > $TMPFILE
while read line
do
    set -- $line
    # Process parameters into variables
    # Note that `LINSOL_' is prepended to the names in the input file
    case $1 in
	INPUT_FORMAT|\
	RANDOM_PARAMETER_FILENAME|\
	MATRIX_DISTRIBUTED|\
	MATRIX_INPUT_FILENAME|\
        MATRIX_OUTPUT_FORMAT|\
	MATRIX_OUTPUT_FILENAME|\
	NUMBER_RHS|\
	RHS_INPUT_FILENAME|\
	INITGUESS|\
	INITGUESS_INPUT_FILENAME|\
	SOLUTIONS_FILENAME|\
	METHOD|\
	ITERATION_MAXIMUM|\
	OUTPUT_DEVICE|\
	MATRIX_NORMALIZED|\
	PRECONDITIONING_METHOD|\
	CHECK_SYSTEM|\
	VERBOSE_LEVEL|\
	NORMALIZATION_METHOD|\
	SMOOTHED|\
	MISC|\
	OPTIMIZE|\
	THRESHOLD|\
	GAUSS_FACTOR|\
	GAUSS_THRES1|\
	GAUSS_THRES2|\
	LDROP_FACTOR|\
	MEMORY_FACTOR|\
	MATRIX_FACTOR|\
	INDEX_FACTOR|\
	INFO_FACTOR|\
	TEMP_DIR|\
	BUFFER_SIZE|\
	RUNTIME_ACCELERATION|\
        BANDW_ALG)
	    eval "VAL=\$LINSOL_$1"
	    if [ "x$VAL" != "x" ]
 	    then
	        echo "WARNING: $1 is set more than once!" 1>&2
	    fi
	    eval "LINSOL_$1=$2"
	    eval "export LINSOL_$1"
	    ;;
	*)
	    echo "WARNING: Unknown parameter $1"
	    ;;
    esac
done < $TMPFILE
rm $TMPFILE

# Convert LINSOL_NPROC into %04d format
LINSOL_NPROC=`sed "s/.*\(....\)$/\1/" << EOF
0000$LINSOL_NPROC
EOF`

# Now check all parameters

notnull LINSOL_INPUT_FORMAT
if [ $LINSOL_INPUT_FORMAT -lt 0 ] || [ $LINSOL_INPUT_FORMAT -gt 3 ]
then
    die "     ERROR: wrong LINSOL-input-format!"
fi

# Call linrand if linsol-input-format = 3
# FIXME: Implement all this locally
if [ $LINSOL_INPUT_FORMAT -eq 3 ]
then
    notnull LINSOL_RANDOM_FILENAME
    echo " *** Converting "$LINSOL_RANDOM_FILENAME
    echo "     into random_input_param_file starts .. ***"
    $LINNOX_EXE_DIR/linrand $LINSOL_RANDOM_FILENAME
fi

if [ $LINSOL_INPUT_FORMAT -ne 3 ]
then
    notnull LINSOL_MATRIX_INPUT_FILENAME
    checkdir `mydirname $LINSOL_MATRIX_INPUT_FILENAME`
fi

if [ "x$LINSOL_MATRIX_DISTRIBUTED" = "x" ] && [ $LINSOL_INPUT_FORMAT -ne 3 ]
then
    echo "     WARNING: it is not specified, if matrix is distributed"
    echo "              default value 0 (i.e. matrix is not distributed)"
    echo "              will be used!"
    LINSOL_MATRIX_DISTRIBUTED=$DEFAULT_MATRIX_DISTRIBUTED
else
    if [ $LINSOL_MATRIX_DISTRIBUTED -ne 0 ] && \
       [ $LINSOL_MATRIX_DISTRIBUTED -ne 1 ] && \
       [ $LINSOL_INPUT_FORMAT -ne 3 ]
    then
	die "     ERROR : Variable DISTRIBUTED must be set to 0 or 1!"
    fi
fi


# check if input-matrix-file exist
if [ $LINSOL_MATRIX_DISTRIBUTED -eq 1 ] && [ $LINSOL_INPUT_FORMAT -ne 3 ]
then
    checkfile ${LINSOL_MATRIX_INPUT_FILENAME}_0001
    checkfile ${LINSOL_MATRIX_INPUT_FILENAME}_$LINSOL_NPROC
else
    if [ $LINSOL_INPUT_FORMAT -ne 3 ]
    then
	checkfile $LINSOL_MATRIX_INPUT_FILENAME
    fi
fi

defaultto LINSOL_MATRIX_OUTPUT_FORMAT $DEFAULT_MATRIX_OUTPUT_FORMAT
if [ $LINSOL_MATRIX_OUTPUT_FORMAT -lt 0 ] || \
   [ $LINSOL_MATRIX_OUTPUT_FORMAT -gt 3 ]
then
    die "     ERROR: wrong matrix-output-format!"
fi


if [ ! $LINSOL_MATRIX_OUTPUT_FORMAT -eq 0 ]
then
    notnull LINSOL_MATRIX_OUTPUT_FILENAME
    checkdir `mydirname $LINSOL_MATRIXOUTPUT_FILENAME`
fi


notnull LINSOL_NUMBER_RHS
if [ $LINSOL_NUMBER_RHS -gt 0 ]
then
    notnullmsg "Please specify filename containing right-hand-side" \
               $LINSOL_RHS_INPUT_FILENAME

    if [ "$LINSOL_MATRIX_DISTRIBUTED" = "1" ]
    then
        checkfile ${LINSOL_RHS_INPUT_FILENAME}_0001
	checkfile ${LINSOL_RHS_INPUT_FILENAME}_$LINSOL_NPROC
    else
        checkfile $LINSOL_RHS_INPUT_FILENAME
    fi
fi


defaultto LINSOL_SOLUTIONS_FILENAME $DEFAULT_SOLUTIONS_FILENAME

defaultto LINSOL_INITGUESS $DEFAULT_INITGUESS
if [ $LINSOL_INITGUESS -lt 0 ] || [ $LINSOL_INITGUESS -gt 1 ]
then
    echo "     WARNING: Wrong value for parameter LINSOL_INITGUESS,"
    echo "              no initial guess will be used!"
    LINSOL_INITGUESS=0
fi

if [ "$LINSOL_INITGUESS" = "1" ]
then
    notnullmsg "File with initial guess not specified!" \
               $LINSOL_INITGUESS_INPUT_FILENAME

    checkfile $LINSOL_INITGUESS_INPUT_FILENAME
fi

defaultto LINSOL_METHOD $DEFAULT_METHOD

defaultto LINSOL_ITERATION_MAXIMUM $DEFAULT_ITERATION_MAXIMUM
if [ $LINSOL_ITERATION_MAXIMUM -gt $LINSOL_MAX_ITMAX ]
then
    echo "Setting LINSOL_ITERATION_MAXIMUM to $DEFAULT_ITERATION_MAXIMUM" 1>&2
    LINSOL_ITERATION_MAXIMUM=$DEFAULT_ITERATION_MAXIMUM
fi


defaultto LINSOL_OUTPUT_DEVICE $DEFAULT_OUTPUT_DEVICE

defaultto LINSOL_NORMALIZATION_METHOD $DEFAULT_NORTMALIZATION_METHOD
if [ $LINSOL_NORMALIZATION_METHOD -gt 14 ]
then
    echo "     ERROR: Value for LINSOL_NORMALIZATION_METHOD not allowed!" 1>&2
    echo "     Set LINSOL_NORMALIZATION_METHOD (> 0 and < 5) or        !" 1>&2
    echo "                                     (> 10 and < 15)         !" 1>&2
    exit 1
fi

defaultto LINSOL_PRECONDITIONING_METHOD $DEFAULT_PRECONDITIONING_METHOD
if [ $LINSOL_PRECONDITIONING_METHOD -gt 100 ]
then
    echo "     ERROR: value for LINSOL_PRECONDITIONING_METHOD not allowed" 1>&2
    echo "     Set LINSOL_PRECONDITIONING_METHOD to < 100!"                1>&2
    exit 1
fi


defaultto LINSOL_CHECK_SYSTEM      $DEFAULT_CHECK_SYSTEM
defaultto LINSOL_VERBOSE_LEVEL     $DEFAULT_VERBOSE_LEVEL
defaultto LINSOL_MATRIX_NORMALIZED $DEFAULT_MATRIX_NORMALIZED
defaultto LINSOL_SMOOTHED          $DEFAULT_SMOOTHED
defaultto LINSOL_MISC              $DEFAULT_MISC
defaultto LINSOL_BANDW_ALG         $DEFAULT_BANDW_ALG

# This is historic cruft.  Delete it at some point...
#if [ [ $MISC -lt 1000 ] || [ [ $MISC -ge 10000 ] && [ $MISC -le 10111 ] ] ] && [ $MOF -eq 2 ]
# then
#  echo "To print matrix in LINSOL-format, set OUTPUT_FORMAT =     2 "
#  echo "                                  and MISC          = $1$$$ "
#  exit 1
#fi

defaultto LINSOL_OPTIMIZE          $DEFAULT_OPTIMIZE
defaultto LINSOL_THRESHOLD         $DEFAULT_THRESHOLD
#defaultto LINSOL_MEMORY_FACTOR     $DEFAULT_MEMORY_FACTOR

defaultto LINSOL_TEMP_DIR /tmp
checkdir `mydirname $LINSOL_TEMP_DIR`

TMPDIR=$LINSOL_TEMP_DIR

notnullmsg "Environment-Variable LINSOL_TEMP_DIR not set" $TMPDIR

echo " ***  Parameters of $PARAMETER_FILE"
echo "      successfully checked !!!                     ***"
echo " ***  Starting UNIX wrapper LINSH  ....            ***"

cd $LINSOL_FILES_DIR

# Pass all arguments down to linsh
$LINNOX_EXE_DIR/linsh $cmdline
