#!/bin/ksh
#
eval `cclargs $0 \
  -npex_low  "1"    "1"    "[lower bound for npex           ]"\
  -npex_high "0"    "0"    "[upper bound for npex           ]"\
  -npey_low  "1"    "1"    "[lower bound for npey           ]"\
  -npey_high "0"    "0"    "[upper bound for npey           ]"\
  -omp       "1"    "1"    "[number of omp threads          ]"\
  -smt       "1"    "2"    "[smt levels                     ]"\
  -low       "0"    "0"    "[lower bound for number of nodes]"\
  -high      "245"  "5000" "[upper bound for number of nodes]"\
  -threads   "3"    "3"    "[number of threads to tun this scripts]"\
  ++ $*`
#
BIN=checkdmpart_${BASE_ARCH}.Abs
AIX=$(echo ${BASE_ARCH} | grep -i AIX)
if [ -z "${AIX}" ] ; then
  CMD=$BIN
else
  CMD="r.mpirun -pgm $BIN"
fi

FN=${TMPDIR}/checkdmpart$$
echo 1 1 | ${CMD} 1> $FN 2> /dev/null
cnt=`grep "CHECKDMPART IS OK" $FN | wc -l`
if [ $cnt -eq 1 ] ; then
  GNI=$(grep GRD_NI $FN | head -n 1 | sed 's/\(.*\)\(GRD_NI\)\( *= *\)\([0-9]*\)/\4/' | cut -d "," -f 1)
  GNJ=$(grep GRD_NJ $FN | head -n 1 | sed 's/\(.*\)\(GRD_NJ\)\( *= *\)\([0-9]*\)/\4/' | cut -d "," -f 1)
  GRDTYP=$(grep GRD_TYP_S $FN | head -n 1 | sed 's/\(.*\)\(GRD_TYP_S\)\( *= *\)\([A-Z]*\)/\4/' | cut -d "," -f 1)
else
  echo 1 1 | ${CMD}
  exit -1
fi
/bin/rm -f $FN $GRDTYP

MAX_threads=${threads}

# when npex_high is not specified, we are considring
# sub-domain sizes larger than 20 on the x-axis

if [ $npex_high -lt 1 ] ; then
  npex_high=$((GNI/20))
fi

# when npey_high is not specified, we are considring
# sub-domain sizes larger than 10 on the y-axis

if [ $npey_high -lt 1 ] ; then
  npey_high=$((GNJ/10))
fi

cnt=$(echo $GRDTYP | grep GY | wc -l)
if [ $cnt -gt 0 ] ; then
  mult=2
else
  mult=1
fi

# Machine specific (AIX P7 at Dorval)
CORESperNODE=32
THREADSperCORE=${smt}
THREADSperNODE=$((CORESperNODE*THREADSperCORE))

echo INVESTIGATING NODES: $((npex_low*npey_low*omp*mult/THREADSperNODE)) $((npex_high*npey_high*omp*mult/THREADSperNODE))
echo with NPEX_LOW= $npex_low NPEX_HIGH= $npex_high NPEY_LOW= $npey_low NPEY_HIGH= $npey_high

chkdomain ()
{
NPEX=$1
NPEY=$2
FN=${TMPDIR}/proctopo$$_$3
out=${4}_$3

nthreads=$((NPEX*NPEY*omp*mult))
nodes=$(echo "scale=3; ${nthreads} / ${THREADSperNODE}" | bc -l)

nodes_int=$(echo ${nodes} | cut -d "." -f1)
FULLNODE=""
if [ $((nodes_int*THREADSperNODE)) -eq ${nthreads} ] ; then
  FULLNODE=FULL_NODE_AIXsmt${smt}
fi 

cores=$(echo "scale=0; ${nodes} * ${CORESperNODE}" | bc -l)
n=$((nthreads/THREADSperNODE))

if [ $n -ge $low -a $n -le $high ] ; then
  echo $NPEX $NPEY | ${CMD} 1> $FN 2> /dev/null
  cnt=`grep "ILLEGAL DOMAIN PARTITIONING" $FN | wc -l`
  if [ $cnt -eq 0 ] ; then
    printf ""TOPO:"%5i "x"%5i  "NODES="%8.2f  "CORES="%6.0f  "MPI="%6i "SUBDOMAINS="%5i "x"%5i %s\n" \
         $NPEX $NPEY $nodes $cores $((NPEX*NPEY*mult)) $((GNI/NPEX)) $((GNJ/NPEY)) ${FULLNODE} >> $out
  fi
  /bin/rm -f $FN
fi
}

FOUNDLISTE=${TMPDIR}/findtopolis$$
rm -f ${FOUNDLISTE}_* ${FOUNDLISTE}TOTAL

noc=0
npex=$npex_low
while [ $npex -le $npex_high ] ; do
  npey=$npey_low
  while [ $npey -le $npey_high ] ; do
    noc=$((noc+1))
    chkdomain $npex $npey $noc ${FOUNDLISTE}_${npex}_${npey} &
    if [ $noc -eq $MAX_threads ] ; then
      wait
      noc=0
    fi
    npey=$((npey+1))
  done
  wait
  cat ${FOUNDLISTE}_${npex}_* 1> ${FOUNDLISTE} 2> /dev/null
  cat ${FOUNDLISTE} 2> /dev/null | sort -k 4 >> ${FOUNDLISTE}TOTAL
  rm -f ${FOUNDLISTE}_${npex}_* ${FOUNDLISTE}
  npex=$((npex+1))
done

if [ -e ${FOUNDLISTE}TOTAL ] ; then
  cat ${FOUNDLISTE}TOTAL
  /bin/rm -f ${FOUNDLISTE}TOTAL 
fi


