#! /bin/sh
#
# This file is used to generate a p4-style procgroup file
#
# This should be used only for pg and execer runs.  It gnerates a list from
# the machines.$arch file
#
# The original csh code made extensive use of csh arrays, which are quite
# nice for reading parts of a file into a variable.
#
if [ "$argsset" = "" ] ; then
   . mpirun.args
fi
#
# Get the defaults (this is in preparation for multi-architecture versions)
# 
if [ $narch = 0 ] ; then
    narch=1
    arch1=$arch
    archlist1="$archlist"
    archlocal=$arch
    np1=$np
fi
if [ $nolocal = 1 ] ; then
    #echo don\'t run local instance
    # if the job is not to be run locally, then don't include this machine
    # in the list
    procFound=0
else
    # echo run local instance
    procFound=1
fi
#
machinelist=""
archuselist=""
curarch=1
nolocalsave=$nolocal
archlocal=$arch1
#
# The first time through the loop, we use the default machinefile, unless
# one has been specified.
#
while [ $curarch -le $narch ] ; do
    eval arch=$"arch$curarch"
    eval archlist=$"archlist$curarch"
    if [ -z "$archlist" ] ; then archlist=$arch ; fi
    eval np=$"np$curarch"
    if [ -z "$np" ] ; then 
	echo "Warning: unspecified -np value for $arch.  Assuming -np 1."
	np=1
    fi
    eval mFile=$"machineFile$curarch"
    if [ -n "$mFile" -a -r "$mFile" ] ; then machineFile=$mFile ; fi
    #
    # Get default machine file
    if [ -z "$machineFile" ] ; then
        # If on the ANL SPx, use getjid to get the machine list...
        if [ "$machine" = "ibmspx" -a -x /usr/local/bin/getjid ] ; then
	    machineFile="/sphome/$LOGNAME/SPnodes.`/usr/local/bin/getjid`"
        else
            for march in $archlist ; do
                machineFile="${MPIR_HOME}/util/machines/machines.${march}"
	        if [ -r $machineFile ] ; then break ; fi
    	    done
        fi
    fi
    #
    if [ -z "$machineFile" -o ! -s "$machineFile" -o \
	! -r "$machineFile" ] ; then
        if [ $nolocal != 0 -o $np != 1 ] ; then
            echo Cannot read $machineFile.  
	    echo Looked for files with extension $archlist in 
	    echo directory ${MPIR_HOME}/util/machines .
            exit 1
        fi
    fi
    #
    # Find the machines to use (build in file).  Note that "local"
    # refers only to the first architecture.
    # 
    if [ $nolocal = 0 -o $curarch -gt 1 ] ; then
        machineavail=`cat $machineFile | \
		sed -e '/^#/d' -e 's/#.*^//g' | head -${np} | \
		tr '\012' ' '`
    else
        if [ $np -gt 1 -o $nolocal = 1 ] ; then
            # Remove host from the list of available machines....
	    # Thanks to Bjarne Herland for modification to 
	    # remove EXACTLY the host machine (eg., bar and not bark)
	    machineavail=`cat $machineFile | sed -e '/^#/d' -e 's/#.*^//g' | \
		    grep -v "^$MPI_HOST\([ -.]\)" | head -${np} | tr '\012' ' '`
	else
	    machineavail=""
        fi
    fi
    #
    # One final refinement.  We could make each job start with
    # different processors with code like
    #r=`date +%S`
    #r=`expr 1 + $r / 10`
    #m1=`echo $machineavail | cut -c $r- -d ' '`
    #r=`expr $r - 1`
    #m2=`echo $machineavail | cut -c 1-$r -d ' '`
    #machineavail="$m1 $m2"
    #
    # Get the machine list for the job
    # KeepHost suggested by Marc A. Viredaz; allows the same machine
    # to be listed multiple times in the machines file.
    # This will loop around the machines list until it
    # finds enough machines (the nfound is used to detect infinite loops)
    # Allow the host to be used if it is the only system found
    #
    KeepHost=0
    loopcnt=0
    while [ $procFound -lt $np ] ; do
        nfound=0
        for machineName in $machineavail ; do
	    if [ $nolocal = 1 -o $KeepHost = 1 -o \
		 $machineName != "$MPI_HOST" ] ; then
	        machinelist="$machinelist $machineName"
		archuselist="$archuselist $arch"
	        procFound=`expr $procFound + 1`
	        nfound=`expr $nfound + 1`
            fi
            if [ $procFound = $np ] ; then break ; fi
	    if [ $machineName = $MPI_HOST ] ; then KeepHost=1 ; fi
        done
        loopcnt=`expr $loopcnt + 1`
        # After the first time, we may have found no hosts BUT now
        # allow KeepHost.  
        if [ $nfound = 0 -a $loopcnt -gt 1 ] ; then
	    echo "Could not find enough machines for architecture $arch"
	    exit 1
        fi
    done
    curarch=`expr $curarch + 1`
    procFound=0
    nolocal=1
    machineFile=""
done
nolocal=$nolocalsave
#
if [ "$argsset" != "1" ] ; then 
    echo $machinelist
    echo $archuselist
    machinehead=""
else
    for machinehead in $machinelist ; do 
	break
    done
fi
