#! /usr/bin/env bash

usage()
{
    echo
    echo "Usage:  $0 [OPTIONS]"
    echo
    echo "where possible OPTIONS are:"
    echo "  (-help|-h)               print usage"
    echo " ---- type of test : ----"
    echo "  (-tlm)                   perform a Tangent-Linear run (defaut: using TAF)"
    echo "  (-adm|-ad)               perform an Adjoint run (default: using TAF)"
    echo "  (-tap)                   use Tapenade for Adjoint or Tangent-Linear run"
    echo "  (-oad)                   perform an OpenAD adjoint run"
    echo "  (-oadsingularity|-oadsngl) STRING"
    echo "                           path to singularity container with OpenAD"
    echo "  (-mth)                   run multi-threaded (using eedata.mth)"
    echo "  (-mpi)                   use MPI to compile and run on 2 processors"
    echo "  (-MPI)  NUMBER           use MPI to compile and run on max NUMBER procs"
    echo "  (-mfile|-mf) STRING      MPI: file with list of possible machines to run on"
    echo "  (-command|-c) STRING     command to run (e.g., if non-standard MPI setting)"
    echo "                            DEF='mitgcmuv' or ='mpirun -np TR_NPROC mitgcmuv'"
    echo " ---- testing options : ----"
    echo "  (-optfile|-of) STRING    optfile to use"
    echo "  (-fast)                  use optfile default for compiler flags (no '-ieee')"
    echo "                            DEF=off => use IEEE numerics option (if available)"
    echo "  (-devel)                 use optfile developement flags (if available)"
    echo "  (-gsl)                   compile with \"-gsl\" flag"
    echo "  (-use_r4|-ur4)           if allowed, use real*4 type for '_RS' variable"
    echo "  (-tdir|-t) STRING        list of group and/or exp. dirs to test"
    echo "                             (recognized groups: basic, tutorials)"
    echo "                             (DEF=\"\" which test all)"
    echo "                             (if list= 'start_from THIS_EXP' then"
    echo "                              test THIS_EXP + all the following)"
    echo "  (-skipdir|-skd) STRING   list of exp. dirs to skip"
    echo "                             (DEF=\"\" which test all)"
    echo "  (-ts)                    provide timing information per timestep"
    echo "  (-papis)                 provide MFlop/s per timestep using PAPI"
    echo "  (-pcls)                  provide MFlop/s per timestep using PCL"
    echo " ---- system options : ----"
    echo "  (-bash|-b) STRING        preferred location of a \"bash\" or \"sh\" shell"
    echo "                             (DEF=\"\" for \"bash\")"
    echo "  (-ef) STRING             used as genmake2 \"-extra_flag\" argument"
    echo "  (-ncad)                  use genmake2 option \"-nocat4ad\" (-ncad)"
    echo "  (-small_f)               make target small_f before making target all"
    echo "  (-makedepend|-md) STRING command to use for \"makedepend\""
    echo "  (-make|-m) STRING        command to use for \"make\""
    echo "                             (DEF=\"make\")"
    echo "  (-j) JOBS                use \"make -j JOBS\" for parallel builds"
    echo " ---- output options : ----"
    echo "  (-match) NUMBER          Matching Criteria (number of digits)"
    echo "                             (DEF=\"$MATCH_CRIT\")"
    echo "  (-pass)                  return non-zero exit code if any exp do not pass"
    echo "  (-odir) STRING           used to build output directory name"
    echo "                             (DEF=\"hostname\")"
    echo "  (-addr|-a) STRING        list of email recipients"
    echo "                             (DEF=\"\" no email is sent)"
    echo "  (-send)       STRING     sending command (instead of using mpack)"
    echo "  (-savdir|-sd) STRING     location to save output tar file to send (DEF='$SAVDIR')"
    echo "  (-mpackdir|-mpd) DIR     location of the mpack utility"
    echo "                             (DEF=\"../tools/mpack-1.6\")"
    echo " -- do only some parts: --"
    echo "  (-clean)                 *ONLY* run \"make CLEAN\" & clean run-dir"
    echo "  (-norun|-nr)             skip the \"runmodel\" stage (stop after make)"
    echo "  (-obj)                   only produces objects (=norun & no executable)"
    echo "  (-src)                   only produces small '*.f' src files (not even obj)"
    echo "                            + with: '-adm/-tlm', also makes taf outp src code"
    echo "  (-runonly|-ro)           *ONLY* run stage (=\"-quick\" without make)"
    echo "  (-quick|-q)              same as \"-nogenmake -noclean -nodepend\""
    echo "  (-nogenmake|-ng)         skip the genmake stage"
    echo "  (-noclean|-nc)           skip the \"make clean\" stage"
    echo "  (-nodepend|-nd)          skip the \"make depend\" stage"
    echo "  (-postclean|-pc)         after each exp. test, clean build-dir & run-dir"
    echo "  (-deloutp|-do)           delete output files after successful run"
    echo "  (-deldir|-dd)            on success, delete the output directory"
    echo
    echo "and where STRING can be a whitespace-delimited list"
    echo "such as:"
    echo
    echo "  -t 'exp0 exp2 exp3' "
    echo "  -addr='abc@123.com testing@home.org'"
    echo
    echo "provided that the expression is properly quoted within the current"
    echo "shell (note the use of single quotes to protect white space)."
    echo
    exit 1
}

#  build the mpack utility
build_mpack()
{
    printf "building the mpack utility...  "
    MPACK="$MPACKDIR/mpack"
    if test ! -x $MPACK ; then
	if test ! -d $MPACKDIR ; then
	    echo
	    echo "Error: can't find \"$MPACKDIR\""
	    echo "  are you sure this program is being run in the correct "
	    echo "  (that is, \"MITGCM_ROOT\verification\") directory?"
	    echo
	    HAVE_MPACK=f
	fi
	if test "x$CC" = x ; then
	    export CC=cc
	fi
	printf "building mpack (using CC=$CC)...  "
	( cd $MPACKDIR && ./configure && $MAKE ) > tr_build_mpack.out 2>&1
	RETVAL=$?
	if test "x$RETVAL" != x0 ; then
	    echo
	    echo "Error building the mpack tools at: $MPACK_DIR"
	    echo
	    HAVE_MPACK=f
	else
	    rm -f tr_build_mpack.out
	    HAVE_MPACK=t
	    echo "done"
	fi
    else
	HAVE_MPACK=t
	echo "already exist"
    fi
}

testoutput_var()
{
    # testoutput_var dir s1 label subdir reference_output
    #
    #  compares 1 variable output selected from file $dir/$subdir/$OUTPUTFILE
    #     with same output from reference file $dir/$reference_output
    #  using search strings s1 and text label

    if [ $debug -gt 0 ]; then
	echo testoutput_var: grep "'$2'" $1/$4/$OUTPUTFILE 1>&2
    fi
    if [ -r $1/$4/$OUTPUTFILE ]; then
	grep "$2" $1/$4/$OUTPUTFILE | sed 's/.*=//' | nl > ${TMP}a.txt
	lncntA=`wc -l ${TMP}a.txt | awk '{print $1}' `
	if [ $lncntA -lt 2 ]; then
	    if [ $verbose -gt 0 ]; then
		echo Not enough lines of output when searching for "$2" 1>&2
	    fi
	    rm -f ${TMP}a.txt ; return 99
	fi
    else
	echo testoutput_var: $OUTPUTFILE from model run was not readable 1>&2
	return 99
    fi
    if [ $debug -gt 0 ]; then
	echo testoutput_var: grep "'$2'" $1/$5 1>&2
    fi
    grep "$2" $1/$5 | sed 's/.*=//' | nl > ${TMP}b.txt
    lncntB=`wc -l ${TMP}b.txt | awk '{print $1}' `
    if [ $lncntB -lt 2 ]; then
	if [ $verbose -gt 0 ]; then
	    echo Not enough lines of output when searching for "$2" 1>&2
	fi
	rm -f ${TMP}a.txt ${TMP}b.txt ; return 99
    fi
    if [ $lncntA -ne $lncntB ]; then
	if [ $verbose -gt 0 ]; then
	    echo Not same Nb of lines when searching for "$2" ":" $lncntA $lncntB 1>&2
	fi
	rm -f ${TMP}a.txt ${TMP}b.txt ; return 99
    fi
    has_nan=`cat ${TMP}a.txt | grep -i nan | wc -l`
    if [ $has_nan -gt 0  ] ; then
	echo testoutput_var: $OUTPUTFILE contains $has_nan NaN values  1>&2
	rm -f ${TMP}a.txt ${TMP}b.txt ; return 99
    fi
    has_inf=`cat ${TMP}a.txt | grep -i inf | wc -l`
    if [ $has_inf -gt 0  ] ; then
	echo testoutput_var: $OUTPUTFILE contains $has_inf Inf values  1>&2
	rm -f ${TMP}a.txt ${TMP}b.txt ; return 99
    fi
    if [ $debug -gt 0 ]; then
	echo testoutput_var: join ${TMP}a.txt ${TMP}b.txt 1>&2
    fi
    # On the SGI O3K (*not* the O2K), "cat -n" inserts a ":" after the line number
    join ${TMP}a.txt ${TMP}b.txt | awk '{print $1 " " $2 " " $3}' | sed -e 's|:||g' > ${TMP}c.txt
    if [ $debug -gt 0 ]; then
	echo testoutput_var: compare_lines 1>&2
    fi
    if [ $verbose -gt 1 ]; then
	cat ${TMP}c.txt 1>&2
    fi
    echo "-1" >> ${TMP}c.txt
    digits_of_similarity=`./tr_cmpnum < ${TMP}c.txt`
    if [ $digits_of_similarity -eq 99 ]; then
	if [ $verbose -gt 0 ]; then
	    echo testoutput_var: No comparison was available for \"$3\" 1>&2
	fi
	digits_of_similarity=99
    else
	if [ $verbose -gt 0 ]; then
	    echo There were $digits_of_similarity decimal places of similarity for \"$3\" 1>&2
	fi
    fi
    rm -f ${TMP}a.txt ${TMP}b.txt ${TMP}c.txt

    return $digits_of_similarity
}

testoutput_run()
{
    # testoutput_run directory subdir reference_output
    #
    #  test output from 1 run in "directory"
# --> same processing for adjoint & forward test
	# default list of output variables to be checked:
	#  1rst : main variable used to decide if it pass or FAIL
	#  others : number of matching digits to be printed in summary.txt
	listChk=$DEF_CHECK_LIST
	#  load experiment-specific list from file "tr_checklist" (if it exist)
	if test -r $1/$2/tr_checklist ; then listChk=`cat $1/$2/tr_checklist` ; fi
	if test $KIND = 1 -o $KIND = 4 ; then kd='g_';
	  #  TLM use same input_ad/tr_checklist --> convert
	  listChk=`echo $listChk | sed 's/^adm/tlm/' | sed 's/ adm/ tlm/g'`
	  if test -r $1/$2/tr_checklist.tlm ; then listChk=`cat $1/$2/tr_checklist.tlm` ; fi
	elif test $KIND = 2 -o $KIND = 5 ; then kd='ad';
	  if test -r $1/$2/tr_checklist.adm ; then listChk=`cat $1/$2/tr_checklist.adm` ; fi
	elif test $KIND = 6 ; then kd='ad';
        else kd=''; fi
	if [ $debug -gt 0 ]; then echo "testoutput_run: listChk='$listChk'" 1>&2 ; fi
	# remove 1rst var and expand the list: + => min max mean s.d
	sVar=`echo $listChk | awk '{print $1}'`
	listVar=`echo $listChk | sed 's/ [a-zA-Z0-9]*+/&mn &mx &av &sd/g' \
			       | sed 's/+//g' | sed "s/^$sVar//"`
	# set ref.outp file-name and, if compressed, uncompress it into subdir
	refoutp=results/$3
	if test ! -r $1/results/$3 ; then
	  if test -r $1/results/${3}.gz ; then
	    tmpNam1=$3
	    tmpNam2=`echo $tmpNam1 | sed 's/\..*\././'`
	    if test "x$tmpNam1" = "x$tmpNam2" ; then
		tmpNam1=`echo $tmpNam2 | sed 's/\./.std./'`
	    fi
	    refoutp=$2/$tmpNam1
	    if [ $debug -gt 0 ]; then
		echo "testoutput_run: gunzip 'results/$3.gz' into '$refoutp'" 1>&2
	    fi
	    gzip -cd $1/results/${3}.gz > $1/$refoutp
	  else
	    echo "missing reference output file '$3' (.gz) in '$1/results/'"
	  fi
	fi
	# check for ptracer output in reference_output file :
	if test $KIND = 0 ; then
	  ptr_mon="trcstat_ptracerXX_min trcstat_ptracerXX_max"
	  ptr_mon="$ptr_mon trcstat_ptracerXX_mean trcstat_ptracerXX_sd"
	  for ii in $PTRACERS_NUM ; do
	    ptrfound=0
	    for jj in $ptr_mon ; do
		name=`eval "echo $jj | sed -e 's|XX|0"$ii"|g'"`
		tst=`grep $name $1/$refoutp | wc -l | awk '{print $1}'`
		if test ! "x$tst" = x0 ; then ptrfound=1 ; fi
	    done
	    if test $ptrfound = '1' ; then
		eval "HAVE_PTR0"$ii"=t"
	    else
		eval "HAVE_PTR0"$ii"=f"
	      # remove this ptr from the list of output variable to check
	      # echo "-- ptr test=" $tst "number of var=" `echo $listVar | awk '{print NF}'` 1>&2
		listVar=`echo "$listVar" | sed "s/ pt$ii..//g"`
	    fi
	  # eval 'echo "HAVE_PTR0'$ii' = $HAVE_PTR0'$ii'"' 1>&2
	  done
	fi
	tst=`echo $sVar $listVar | awk '{ for(i=2;i<=NF;i++){if($i==$1)t+=1}; print t }'`
	if test $tst != 1 ; then
	  if test $tst = 0 ; then echo "==> WARNING: selected var >$sVar< not found" 1>&2
		 else echo "==> WARNING: found selected var >$sVar< $tst times" 1>&2 ; fi
	  echo "==> WARNING: in checked list:" $listVar 1>&2
	#- put it back once:
	  listVar=" $sVar "`echo "$listVar " | sed "s/ $sVar / /g"`
	fi
	if [ $debug -gt 0 ]; then echo "testoutput_run: listVar='$listVar'" 1>&2 ; fi
	echo "listVar='$listVar'" >> $locDIR"/summary.txt"
	#---
	allargs=""
	for xx in $listVar
	do
         #ii=`echo $xx | sed 's/^pt[0-9][0-9]*..$/XXX/'`	#- any ptr number
          ii=`echo $xx | sed 's/^pt[1-9]..$/XXX/'`		#- 1 to 9 ptr number
          if test $ii != 'XXX' ; then
          #- all except ptracer stats:
	    case $xx in
	   'PS')  if [ $debug -gt 0 ]
		  then echo testoutput_run: testoutput_var $1 cg2d_init_res 1>&2 ; fi
		  testoutput_var $1 "cg2d_init_res" "Press. Solver (cg2d)" $2 $refoutp ; yy=$?
		  if [ $debug -gt 0 ] ; then echo testoutput_run: cg2dres=$yy 1>&2 ; fi ;;
	'admCst') testoutput_var $1 "ADM  ref_cost_function" "ADM CostFct" $2 $refoutp ; yy=$? ;;
	'admGrd') testoutput_var $1 "ADM  adjoint_gradient"  "ADM Ad Grad" $2 $refoutp ; yy=$? ;;
	'admFwd') testoutput_var $1 "ADM  finite-diff_grad"  "ADM FD Grad" $2 $refoutp ; yy=$? ;;
	'tlmCst') testoutput_var $1 "TLM  ref_cost_function" "TLM CostFct" $2 $refoutp ; yy=$? ;;
	'tlmGrd') testoutput_var $1 "TLM  tangent-lin_grad"  "TLM TL Grad" $2 $refoutp ; yy=$? ;;
	'tlmFwd') testoutput_var $1 "TLM  finite-diff_grad"  "TLM FD Grad" $2 $refoutp ; yy=$? ;;
	   'Tmn') testoutput_var $1 "dynstat_${kd}theta_min"  "${kd}Theta minimum" $2 $refoutp ; yy=$? ;;
	   'Tmx') testoutput_var $1 "dynstat_${kd}theta_max"  "${kd}Theta maximum" $2 $refoutp ; yy=$? ;;
	   'Tav') testoutput_var $1 "dynstat_${kd}theta_mean" "${kd}Theta mean"	   $2 $refoutp ; yy=$? ;;
	   'Tsd') testoutput_var $1 "dynstat_${kd}theta_sd"   "${kd}Theta Std.Dev" $2 $refoutp ; yy=$? ;;
	   'Smn') testoutput_var $1 "dynstat_${kd}salt_min"   "${kd}Salt minimum"  $2 $refoutp ; yy=$? ;;
	   'Smx') testoutput_var $1 "dynstat_${kd}salt_max"   "${kd}Salt maximum"  $2 $refoutp ; yy=$? ;;
	   'Sav') testoutput_var $1 "dynstat_${kd}salt_mean"  "${kd}Salt mean"	   $2 $refoutp ; yy=$? ;;
	   'Ssd') testoutput_var $1 "dynstat_${kd}salt_sd"    "${kd}Salt Std.Dev"  $2 $refoutp ; yy=$? ;;
	   'Umn') testoutput_var $1 "dynstat_${kd}uvel_min"   "${kd}U minimum"	   $2 $refoutp ; yy=$? ;;
	   'Umx') testoutput_var $1 "dynstat_${kd}uvel_max"   "${kd}U maximum"	   $2 $refoutp ; yy=$? ;;
	   'Uav') testoutput_var $1 "dynstat_${kd}uvel_mean"  "${kd}U mean"	   $2 $refoutp ; yy=$? ;;
	   'Usd') testoutput_var $1 "dynstat_${kd}uvel_sd"    "${kd}U Std.Dev"	   $2 $refoutp ; yy=$? ;;
	   'Vmn') testoutput_var $1 "dynstat_${kd}vvel_min"   "${kd}V minimum"	   $2 $refoutp ; yy=$? ;;
	   'Vmx') testoutput_var $1 "dynstat_${kd}vvel_max"   "${kd}V maximum"	   $2 $refoutp ; yy=$? ;;
	   'Vav') testoutput_var $1 "dynstat_${kd}vvel_mean"  "${kd}V mean"	   $2 $refoutp ; yy=$? ;;
	   'Vsd') testoutput_var $1 "dynstat_${kd}vvel_sd"    "${kd}V Std.Dev"	   $2 $refoutp ; yy=$? ;;
	 'Etamn') testoutput_var $1 "dynstat_${kd}eta_min"    "${kd}Eta minimum"   $2 $refoutp ; yy=$? ;;
	 'Etamx') testoutput_var $1 "dynstat_${kd}eta_max"    "${kd}Eta maximum"   $2 $refoutp ; yy=$? ;;
	 'Etaav') testoutput_var $1 "dynstat_${kd}eta_mean"   "${kd}Eta mean"	   $2 $refoutp ; yy=$? ;;
	 'Etasd') testoutput_var $1 "dynstat_${kd}eta_sd"     "${kd}Eta Std.Dev"   $2 $refoutp ; yy=$? ;;
	 'Qntmn') testoutput_var $1 "forcing_qnet_min"  "Qnet minimum"  $2 $refoutp ; yy=$? ;;
	 'Qntmx') testoutput_var $1 "forcing_qnet_max"  "Qnet maximum"  $2 $refoutp ; yy=$? ;;
	 'Qntav') testoutput_var $1 "forcing_qnet_mean" "Qnet mean"	$2 $refoutp ; yy=$? ;;
	 'Qntsd') testoutput_var $1 "forcing_qnet_sd"   "Qnet Std.Dev"  $2 $refoutp ; yy=$? ;;
	 'aSImn') testoutput_var $1 "seaice_${kd}area_min"  "SIce ${kd}Area min"   $2 $refoutp ; yy=$? ;;
	 'aSImx') testoutput_var $1 "seaice_${kd}area_max"  "SIce ${kd}Area max"   $2 $refoutp ; yy=$? ;;
	 'aSIav') testoutput_var $1 "seaice_${kd}area_mean" "SIce ${kd}Area mean"  $2 $refoutp ; yy=$? ;;
	 'aSIsd') testoutput_var $1 "seaice_${kd}area_sd"   "SIce ${kd}Area StDv"  $2 $refoutp ; yy=$? ;;
	 'hSImn') testoutput_var $1 "seaice_${kd}heff_min"  "SIce ${kd}Heff min"   $2 $refoutp ; yy=$? ;;
	 'hSImx') testoutput_var $1 "seaice_${kd}heff_max"  "SIce ${kd}Heff max"   $2 $refoutp ; yy=$? ;;
	 'hSIav') testoutput_var $1 "seaice_${kd}heff_mean" "SIce ${kd}Heff mean"  $2 $refoutp ; yy=$? ;;
	 'hSIsd') testoutput_var $1 "seaice_${kd}heff_sd"   "SIce ${kd}Heff StDv"  $2 $refoutp ; yy=$? ;;
	 'uSImn') testoutput_var $1 "seaice_${kd}uice_min"  "SIce ${kd}Uice min"   $2 $refoutp ; yy=$? ;;
	 'uSImx') testoutput_var $1 "seaice_${kd}uice_max"  "SIce ${kd}Uice max"   $2 $refoutp ; yy=$? ;;
	 'uSIav') testoutput_var $1 "seaice_${kd}uice_mean" "SIce ${kd}Uice mean"  $2 $refoutp ; yy=$? ;;
	 'uSIsd') testoutput_var $1 "seaice_${kd}uice_sd"   "SIce ${kd}Uice StDv"  $2 $refoutp ; yy=$? ;;
	 'vSImn') testoutput_var $1 "seaice_${kd}vice_min"  "SIce ${kd}Vice min"   $2 $refoutp ; yy=$? ;;
	 'vSImx') testoutput_var $1 "seaice_${kd}vice_max"  "SIce ${kd}Vice max"   $2 $refoutp ; yy=$? ;;
	 'vSIav') testoutput_var $1 "seaice_${kd}vice_mean" "SIce ${kd}Vice mean"  $2 $refoutp ; yy=$? ;;
	 'vSIsd') testoutput_var $1 "seaice_${kd}vice_sd"   "SIce ${kd}Vice StDv"  $2 $refoutp ; yy=$? ;;
	'AthSiG') testoutput_var $1 "thSI_Ice_Area_G" "thSIc Area Global" $2 $refoutp ; yy=$? ;;
	'AthSiS') testoutput_var $1 "thSI_Ice_Area_S" "thSIc Area South"  $2 $refoutp ; yy=$? ;;
	'AthSiN') testoutput_var $1 "thSI_Ice_Area_N" "thSIc Area North"  $2 $refoutp ; yy=$? ;;
	'HthSiG') testoutput_var $1 "thSI_IceH_ave_G" "thSIc H Glob-ave"  $2 $refoutp ; yy=$? ;;
	'HthSiS') testoutput_var $1 "thSI_IceH_ave_S" "thSIc H South-av"  $2 $refoutp ; yy=$? ;;
	'HthSiN') testoutput_var $1 "thSI_IceH_ave_N" "thSIc H North-av"  $2 $refoutp ; yy=$? ;;
	'HthMxS') testoutput_var $1 "thSI_IceH_max_S" "thSIc H South-max" $2 $refoutp ; yy=$? ;;
	'HthMxN') testoutput_var $1 "thSI_IceH_max_N" "thSIc H North-max" $2 $refoutp ; yy=$? ;;
	 'sbo_M') testoutput_var $1 "sbo_mass"          "SBO mass"	  $2 $refoutp ; yy=$? ;;
	 'sboFW') testoutput_var $1 "sbo_mass_fw"       "SBO m-FW"	  $2 $refoutp ; yy=$? ;;
	 'sboAc') testoutput_var $1 "sbo_zoamc"         "SBO AM-C"	  $2 $refoutp ; yy=$? ;;
	 'sboAp') testoutput_var $1 "sbo_zoamp"         "SBO AM-P"	  $2 $refoutp ; yy=$? ;;
	'StrmIc') testoutput_var $1 "STREAMICE_FP_ERR" "StreamIce Solver" $2 $refoutp ; yy=$? ;;
	      *) yy=99; echo "WARNING: asking for var=$xx : not recognized !" 1>&2 ;;
	    esac
          else
          #- ptracers stats:
            nn=`echo $xx | sed 's/pt//' | sed 's/..$//'`
            ii=`echo $xx | sed 's/^pt[0-9]*//'`
	    case $ii in
	    'mn') testoutput_var $1 "trcstat_${kd}ptracer0"$nn"_min"  "${kd}pTr0"$nn"_min"  $2 $refoutp ; yy=$? ;;
	    'mx') testoutput_var $1 "trcstat_${kd}ptracer0"$nn"_max"  "${kd}pTr0"$nn"_max"  $2 $refoutp ; yy=$? ;;
	    'av') testoutput_var $1 "trcstat_${kd}ptracer0"$nn"_mean" "${kd}pTr0"$nn"_mean" $2 $refoutp ; yy=$? ;;
	    'sd') testoutput_var $1 "trcstat_${kd}ptracer0"$nn"_sd"   "${kd}pTr0"$nn"_StDv" $2 $refoutp ; yy=$? ;;
	    esac
          fi
	  if test $xx = $sVar
	  then allargs="$allargs > $yy <"
	  else allargs="$allargs $yy"
	  fi
	done

	nbVar=`echo $listVar | awk '{print NF}'`
	if [ $nbVar -lt $LEN_CHECK_LIST ] ; then
	#-- fill line (up to standard length) with dot:
	  adNul=`expr $LEN_CHECK_LIST - $nbVar | awk '{for(i=1;i<=$1;i++){print "."}}'`
	  echo $allargs $adNul
	else
	  echo $allargs
        fi
# <-- same processing for adjoint & forward test
}

genmakemodel()
{
    # genmakemodel directory
    if test "x$NOGENMAKE" = xt ; then
	echo "genmake skipped!"
    else
	if test "x$BASH" = x ; then
	    GENMAKE2="../../../tools/genmake2"
	else
	    GENMAKE2="$BASH ../../../tools/genmake2 -bash $BASH"
	fi
	(
	    cd $1;
	    command="$GENMAKE2  -ds -m $MAKE"
	    if test "x$MKDEPEND" != x ; then
		command="$command -makedepend=$MKDEPEND"
	    fi
	    if test $KIND = 6 ; then
		command="$command -oad -mods=../$code_dir"
	    elif [ $KIND -ge 3 ] ; then
		command="$command -tap -mods=../$code_dir"
	    else
		command="$command -mods=../$code_dir"
	    fi
	    if test "x$OPTFILE" != xNONE ; then
		command="$command -optfile=$OPTFILE"
	    fi
	    if test $OptLev = 1 ; then
		command="$command -ieee"
	    fi
	    if test $OptLev = 0 ; then
		command="$command -devel"
	    fi
	    if test "x$GSL" = xt ; then
		command="$command -gsl"
	    fi
	    if test "x$MPI" != x0 ; then
		command="$command -mpi"
	    fi
	    if test "x$MULTI_THREAD" = xt ; then
	    #- run multi-threaded using OpenMP:
		command="$command -omp"
	    fi
	    if test "x$USE_R4" = xt ; then
		command="$command -use_r4"
	    fi
	    if test "x$EXTRFLG" != x ; then
		command="$command -extra_flag $EXTRFLG"
	    fi
	    if test "x$NOCATAD" = xt ; then
		command="$command -nocat4ad"
	    fi
	    if test "x$TS" = xt ; then
		command="$command -ts"
	    fi
	    if test "x$PAPIS" = xt ; then
		command="$command -papis"
	    else
	    if test "x$PCLS" = xt ; then
		command="$command -pcls"
	    fi
	    if test "x$OADSINGULARITY" != x ; then
		command="$command -oadsingularity \"$OADSINGULARITY\""
	    fi
	    fi
	    printf 'genmake ... '
	    eval $command > genmake.tr_log 2>&1
	    RETVAL=$?
	    #  Reduce the size of the testing emails!
	    head -100 Makefile > $CDIR/Makefile_head
	    if test "x$RETVAL" != x0 ; then
		tail genmake.tr_log
		echo "genmakemodel: genmake failed"
		cp genmake.log genmake_* genmake.tr_log $CDIR
		return 1
	    else
		echo "successful"
	    fi
	)
    fi
}

makeclean()
{
    # makeclean directory
    if test "x$NOGENMAKE" = xf ; then rm -f $1/make.tr_log ; fi
    if test "x$NOCLEAN" = xt ; then
	echo "make Clean skipped!"
    else
	(
	    cd $1;
	    #if test -e $OUTPUTFILE ; then rm -f $OUTPUTFILE ; fi
	    if test -r Makefile ; then
		printf 'clean build-dir: make Clean ... '
		$MAKE Clean >> make.tr_log 2>&1
		RETVAL=$?
		if test "x$RETVAL" != x0 ; then
		    tail make.tr_log
		    echo "makeclean: \"make Clean\" failed"
		    cp make.tr_log genmake.log genmake.tr_log $CDIR
		    return 1
		fi
		echo successful
	    else
		echo ''
	    fi
	    exit 0
	)
    fi
}

run_clean()
{
    # run_clean directory
    if test "x$NOCLEAN" = xt ; then
	echo "run_clean skipped!"
    else
      (
	cd $1;
	printf 'clean run-dir ... '
	# part of what is done after "make clean" when doing "make CLEAN"
	find . -name "*.meta" -exec rm {} \;
	find . -name "*.data" -exec rm {} \;
	find . -name "*.tmp"  -exec rm {} \;
	find . -name "fort.*" -exec rm {} \;
	find . -type l -exec rm {} \;
	#- should remove executable only if sym-link (already done above)
	rm -f $RUNLOG *.txt STDOUT.* STDERR.* *diagnostics.log *.[0-9][0-9][0-9][0-9].log
	rm -f datetime costfinal divided.ctrl snapshot* output_adm.*.diva_*
	rm -f *_MIT_CE_000.opt0000 costfunction*0000
	rm -f oad_cp.[0-9][0-9][0-9].?????
	rm -rf mnc_test_*
	echo successful
	exit 0
      )
    fi
}

makedependmodel()
{
    # makedependmodel directory
    if test "x$NODEPEND" = xt ; then
	echo "make depend skipped!"
    else
	(
	    cd $1;
	    printf 'make depend ... '
	    $MAKE depend >> make.tr_log 2>&1
	    RETVAL=$?
	    if test "x$RETVAL" != x0 ; then
		tail make.tr_log
		echo "makedependmodel: make depend failed"
		cp make.tr_log genmake.log genmake.tr_log $CDIR
		return 1
	    else
		echo successful
	    fi
	)
    fi
}

makemodel()
{
    # makemodel directory
    (
    mk_fail=0
    if test "x$NOMAKE" = xt ; then
	cd $1;
	if test -x $EXECUTABLE ; then
	    echo "make skipped!"
	else
	    echo "no executable!"
	    mk_fail=3
	fi
    else
	cd $1;
	if test -r Makefile ; then
	    if test "x$MKSMALLF" = xt ; then
		printf 'make small_f ... '
		$MAKE_CMD small_f >> make.tr_log 2>&1
		RETVAL=$?
		if test "x$RETVAL" != x0 ; then
		    tail make.tr_log
		    echo failed
		    cp genmake.log genmake.tr_log $CDIR
		    tail -$NBLINES_MKLOG make.tr_log > $CDIR"/make.tr_log_tail"
		    rm -f $EXECUTABLE
		    mk_fail=1
		else
		    echo successful
		fi
	    fi
	    printf "make $TARG ... "
	    $MAKE_CMD $TARG >> make.tr_log 2>&1
	    RETVAL=$?
	    if test "x$RETVAL" != x0 ; then
		tail make.tr_log
		echo failed
		cp genmake.log genmake.tr_log $CDIR
		tail -$NBLINES_MKLOG make.tr_log > $CDIR"/make.tr_log_tail"
		rm -f $EXECUTABLE
		mk_fail=1
	    else
		echo successful
	    fi
	else
	    echo "no Makefile !"
	    mk_fail=2
	fi
    fi
    if test $KIND = 1 -a -f taf_ftl.log ; then
	grep 'Processing files at' make.tr_log | tail -1 >> $CDIR"/summary.txt"
	head -1 taf_ftl.log >> $CDIR"/summary.txt"
    fi
    if test $KIND = 2 -a -f taf_ad.log ; then
	grep 'Processing files at' make.tr_log | tail -1 >> $CDIR"/summary.txt"
	head -1 taf_ad.log >> $CDIR"/summary.txt"
	nerr=`grep -c 'TAF *.* ERROR ' taf_ad.log`
	nwar=`grep -c '^TAF *.* RECOMPUTATION *.* WARNING ' taf_ad.log`
	if test -f taf_output ; then
	    n2er=`grep -c 'TAF *.* ERROR ' taf_output`
	    n3er=`grep -c '\*ERROR\* ' taf_output`
	    nerr=`expr $nerr + $n2er + $n3er`
	fi
	echo " TAF reports $nerr Errors and $nwar Recomputation Warnings" \
				>> $CDIR"/summary.txt"
	#- report number of calls for some key S/R, i.e.,
	#   load_fields_driver, do_oceanic_phys, and seaice_model
	#  Multiple calls indicate hidden but expensive recomputations
	FS='f'
	if test -f genmake_state ; then eval `grep '^FS=' genmake_state` ; fi
	if test "x$NOCATAD" = xt ; then
	    adfiles="*_ad.$FS"
	else
	    adfiles=ad_taf_output.$FS
	fi
	nbf=`ls $adfiles 2> /dev/null | wc -l`
	if [ $nbf -eq 0 ] ; then
	    echo "WARNING: no adfiles '$adfiles' found" >> $CDIR"/summary.txt"
	    nlfd=0 ; ndop=0 ; nsm=0
	else
	    nlfd=`grep "call load_fields_driver(" ${adfiles} | wc -l`
	    nlfdmd=`grep "call load_fields_drivermd(" ${adfiles} | wc -l`
	    nlfd=$((nlfd+nlfdmd-1))
	    ndop=`grep "call do_oceanic_phys(" ${adfiles} | wc -l`
	    nsm=`grep "call seaice_model(" ${adfiles} | wc -l`
	fi
	echo " load_fields_driver, do_oceanic_phys, seaice_model are called " \
	     "( $nlfd , $ndop , $nsm ) time(s)" >> $CDIR"/summary.txt"
    fi
    if test -f make.tr_log && test $KIND = 4 -o $KIND = 5 ; then
	grep '^Tapenade ' make.tr_log | tail -n 1 >> $CDIR"/summary.txt"
    fi
    if test $mk_fail != 0 ; then return $mk_fail ; fi
    )
}

mk_mpi_size()
{
    # mk_mpi_size input_file output_file proc_Nb threads_Nb_X threads_Nb_Y
    #
    #  make new SIZE.h (=output_file) from SIZE.h_mpi (=input_file)
    #     for an MPI build with no more than proc_Nb processors ;
    #  ensure that enough tiles per proc (nSx,nSy) remain for the given
    #     number of threads (nTx,nTy) ;
    #  return the effective number of processors.

    inp=$1
    out=$2
    np=$3
    tx=$4
    ty=$5
    tmp=TTT.$$

    # dirX : select with direction to favor in MPI process repartition
    #   dirX=1 : prefer to put more proc in X direction
    #   dirX=0 : prefer to put more proc in Y direction
    dirX=0

    px=`grep "^     & *nPx *=" $inp | sed "s/^     & *nPx *= *//" | sed 's/, *$//'`
    py=`grep "^     & *nPy *=" $inp | sed "s/^     & *nPy *= *//" | sed 's/, *$//'`
    sx=`grep "^     & *nSx *=" $inp | sed "s/^     & *nSx *= *//" | sed 's/, *$//'`
    sy=`grep "^     & *nSy *=" $inp | sed "s/^     & *nSy *= *//" | sed 's/, *$//'`

    #- for each direction, assume # of threads is a multiple of total number of tiles
    nx=$px
    if [ `expr $sx % $tx` -ne 0 -a `expr $sx \* $px % $tx` -eq 0 ] ; then
	nx=`expr $sx \* $px / $tx`
	if [ $verbose -gt 1 ]; then
	    echo " change px from $px to $nx to accommodate $tx threads"
	fi
    fi
    ny=$py
    if [ `expr $sy % $ty` -ne 0 -a `expr $sy \* $py % $ty` -eq 0 ] ; then
	ny=`expr $sy \* $py / $ty`
	if [ $verbose -gt 1 ]; then
	    echo " change py from $py to $ny to accommodate $ty threads"
	fi
    fi
    #- find the largest divisor of input_file proc Nb, but not larger than $np
    pp=0
    i=1
    while [ $i -le $nx ] ; do
      if [ `expr $nx % $i` -eq 0 ] ; then
	j=1
	while [ $j -le $ny ] ; do
	  if [ `expr $ny % $j` -eq 0 ] ; then
	    ij=`expr $i \* $j`
	    if [ $ij -gt $pp ] ; then
		flag=1
	    elif [ $ij -eq $pp ] ; then
		flag=$dirX
	    else
		flag=0
	    fi
	    if test $flag = 1 ; then
	      if [ $ij -le $np ] ; then
		ix=$i ; jy=$j ; pp=$ij
		#echo "  ix,jy= $ix,$jy"
	      fi
	    fi
	  fi
	  j=`expr $j + 1`
	done
      fi
      i=`expr $i + 1`
    done

    #- create new SIZE.h type file:
    sx=`expr $sx \* $px / $ix`
    sy=`expr $sy \* $py / $jy`
    if [ $verbose -gt 1 ]; then
	echo " px,py,np= $px,$py,$np : New MPI size: px,py= $ix,$jy : sx,sy= $sx,$sy"
    fi
    sed "/^     \& *nPx *=/s/[0-9]*,/$ix,/" $inp > $tmp
    sed "/^     \& *nPy *=/s/[0-9]*,/$jy,/" $tmp > $out
    sed "/^     \& *nSx *=/s/[0-9]*,/$sx,/" $out > $tmp
    sed "/^     \& *nSy *=/s/[0-9]*,/$sy,/" $tmp > $out
    rm -f $tmp
    return $pp
}

symlink_mpifiles()
{
    # Put special links so that MPI specific files are used
    # This MUST be invoked between makeclean and makelinks because
    # the Makefile will link to non-mpi files by default

    dir=$1
    code_dir=$2
    build_dir=$dir/$3

    # These are files that should replace their counter-part when using -mpi
    MPI_FILES=`(cd $dir/$code_dir; find . -name "*_mpi" -print)`

    for ii in $MPI_FILES ; do
	i=`echo $ii | sed 's:^\./::'`
	name=`echo $i | sed 's:_mpi::'`
	file="../$code_dir/$i"
	if test $name = 'SIZE.h' ; then file="SIZE.h.mpi" ; fi

	#  Is this an MPI run?
	if test "x$MPI" = x0 ; then
	    # NO: We undo any _mpi symbolically linked files
	    if test -L $build_dir/$name ; then
		( cd $build_dir ; cmp $name $file > /dev/null 2>&1 )
		RETVAL=$?
		if test "x$RETVAL" = x0 ; then
		    if [ $verbose -gt 1 ]; then
			echo "  Un-linking $name from ../$code_dir" ; fi
		    rm -f $build_dir/$name
		fi
	    fi
	else
	    # YES: We symbolically link these files to the build
	    # dir so long as there is no real file in place
	    ( cd $build_dir ; cmp $name $file > /dev/null 2>&1 )
	    RETVAL=$?
	    if [ $verbose -gt 1 ]; then echo "  cmp $name $file returns: $RETVAL" ; fi
	    if test "x$RETVAL" != x0 ; then
		if test -h $build_dir/$name ; then rm -f $build_dir/$name ; fi
		if test ! -r $build_dir/$name ; then
		    if [ $verbose -gt 1 ]; then echo "  Linking $name to $file" ; fi
		    (cd $build_dir; ln -sf $file $name)
		fi
	    fi
	fi
    done
}

linkdata()
{
    # linkdata run_dir input_dir_1 input_dir_2 ...
    #
    # symbolically link data files to run directory
    if test -d $1 ; then
	(
	    cd $1 ; shift
	    echo 'linkdata from dirs:' $*
	    inpMPI=`(cd ../$1 ; find . -name "*.mpi" -print | sed 's:^\./::')`
	    for xx in $inpMPI ; do
	      if test -r "../"$1"/"$xx ; then
		# found 1 .mpi sfx file in 1rst input dir and it is readable
		yy=`echo $xx | sed 's:\.mpi$::'`
		if test "x$MPI" = "x0" ; then
		    # not mpi test: remove symbolic link
		    if test -h $yy ; then rm -f $yy ; fi
		else
		    # mpi test: remove symbolic link & link .mpi sfx file
		    if test -h $yy ; then rm -f $yy ; fi
		    if test ! -r $yy ; then
			ln -sf "../"$1"/"$xx $yy ;
			printf " $xx" 1>&2
		    fi
		fi
	      fi
	    done
	    if test -r "../"$1"/eedata.mth" ; then
	    # found eedata.mth in 1rst input dir and it is readable
		if test "x$MULTI_THREAD" = "xt" ; then
		# multi-threaded test: remove symbolic link & link eedata.mth
		    if test -h eedata ; then rm -f eedata ; fi
		    if test ! -r eedata ; then
			ln -sf "../"$1"/eedata.mth" eedata ;
			printf ' eedata.mth' 1>&2
		    fi
		else
		# not multi-threaded test: remove eedata symbolic link
		    if test -h eedata ; then rm -f eedata ; fi
		fi
	    fi
	    prevDir='NONE'
	    for ldir in $* ; do
		if test -d "../"$ldir -a $ldir != $prevDir ; then
		    printf " ldir=${ldir}:" 1>&2
		    files=`( cd "../"$ldir ; ls -1 | grep -v CVS )`
		    for i in $files ; do
			if test ! -d "../"$ldir/$i ; then
			    if test ! -r $i  ; then
				printf ' '$i 1>&2
				ln -sf "../"$ldir"/"$i $i
			    fi
			fi
		    done
		    printf ' ;\n' 1>&2
		fi
		prevDir=$ldir
	    done
	    if test -x prepare_run ; then
		./prepare_run 1>&2
	    fi
	)
    fi
}

runmodel()
{
    # runmodel directory
    #
    #  runs $COMMAND in "directory"
    #  (where "$COMMAND" is relative to "directory")
    (
	cd $1
	printf 'runmodel in %s ... ' $1
	if test "x$MPI" != x0 ; then
	    #- adjust the MPI run command with the right number of Procs
	    #echo '' ; echo "  COMMAND='$COMMAND'"
	    COMMAND=`echo $COMMAND | sed "s/ TR_NPROC/ $LOC_NPROC/"`
	    if test "x$MPI_MFILE" != x ; then
	      COMMAND=`echo $COMMAND | sed "s/ TR_MFILE / ..\/$LOC_MFILE /"`
	    fi
	    #echo "  COMMAND='$COMMAND'"
	fi
	if test -L $EXECUTABLE ; then
	  if test -x "../"$builddir"/"$EXECUTABLE ; then
	    cmp $EXECUTABLE "../"$builddir"/"$EXECUTABLE > /dev/null 2>&1
	    outD=$? ; if test "x$outD" != x0 ; then rm -f $EXECUTABLE ; fi
	  else rm -f $EXECUTABLE
	  fi
	fi
	if test ! -x $EXECUTABLE -a -x "../"$builddir"/"$EXECUTABLE ; then
	    echo " link" $EXECUTABLE "from dir ../"$builddir > run.log_tmp
	    ln -sf "../"$builddir"/"$EXECUTABLE .
	fi
	if test ! -x $EXECUTABLE ; then
	    rm -f $RUNLOG ; touch $RUNLOG
	    if test -f run.log_tmp ; then cat run.log_tmp >> $RUNLOG ; fi
	    echo " no executable:" $EXECUTABLE >> $RUNLOG
	    RETVAL=8
	    ENDVAL=-1
	else
	  if test ! -f $OUTPUTFILE -o $OUTPUTFILE -ot $EXECUTABLE ; then
	    # output do not exist or is older than executable:
	    rm -f $OUTPUTFILE $RUNLOG ; touch $RUNLOG
	    if test -f run.log_tmp ; then cat run.log_tmp >> $RUNLOG ; fi
	#- Divided Adjoint Run:
	    add_DIVA_runs=0
	#  get the number of additional runs (add_DIVA_runs) from file "run_ADM_DIVA"
	    if test $KIND = 2 -a -f run_ADM_DIVA ; then
	      adm_diva_nb=`sed -n '/^ *add_DIVA_runs *=/p' run_ADM_DIVA | sed 's/ //g'`
	      echo " Divided Adjoint Run: $adm_diva_nb" >> $RUNLOG
	      eval "let $adm_diva_nb"
	      if [ $add_DIVA_runs -ge 1 ] ; then
		extraRuns=`expr $add_DIVA_runs - 1`
		rm -f costf* divided.ctrl snapshot*
		echo -n "(add_DIVA_runs=$add_DIVA_runs) ... "
		for ii in `seq 0 $extraRuns` ; do
		  ( eval $COMMAND ) >> $RUNLOG 2>&1
		  echo " additional DIVA run # $ii : done" >> $RUNLOG
		  mv -f $OUTPUTFILE ${OUTPUTFILE}.diva_${ii}
		done
	      fi
	    elif test -f run_ADM_DIVA ; then
		rm -f costf* divided.ctrl snapshot*
	    fi
	#- special DIVA processing ends here
	    ( eval $COMMAND ) >> $RUNLOG 2>&1
	    RETVAL=$?
	    ENDVAL=`tail $OUTPUTFILE | grep -c 'PROGRAM MAIN: Execution ended Normally'`
	    if [ $POSTCLEAN -eq 1 -a $ENDVAL -gt 0 ] ; then
		find . -name "*.meta" -exec rm {} \;
		find . -name "*.data" -exec rm {} \;
		rm -rf mnc_test_*
	    fi
	  else
	    RETVAL=0
	    ENDVAL=`tail $OUTPUTFILE | grep -c 'PROGRAM MAIN: Execution ended Normally'`
	    touch $RUNLOG
	    if test -f run.log_tmp ; then cat run.log_tmp >> $RUNLOG ; fi
	    echo "---------->> $OUTPUTFILE is up to date" >> $RUNLOG 2>&1
	  fi
	fi
	rm -f run.log_tmp
	#- in all cases where OutputFile exists, report SIZE and time
	if test -f $OUTPUTFILE ; then
	  grep '(PID\.TID 0000\.0001)      n.. =' $OUTPUTFILE \
		| sed 's/(PID.TID 0000.0001)   //' >> $CDIR"/summary.txt"
#	  grep -A3 'Seconds in section "ALL' $OUTPUTFILE \
#		| sed 's/(PID.TID 0000.0001)   //' >> $CDIR"/summary.txt"
#         some implementations of grep cannot do contextual searches so we
#         replace the above with a sed command
	  cat $OUTPUTFILE | sed -n '/Seconds in section "ALL/{N
	  N
	  N
	  p
	  }' | sed 's/(PID.TID 0000.0001)   //' >> $CDIR"/summary.txt"
	fi
	if test -s STDERR.0000 ; then cp STDERR.0000 $CDIR"/STDERR.0000" ; fi
	if [ $RETVAL -eq 0 -a $ENDVAL -gt 0 ] ; then
	    echo successful
	    printf '=> output from running in %s :\n' $1 1>&2
	    tail $RUNLOG | sed 's/^.*/> &/g' 1>&2
	    return 0
	elif [ $RETVAL -ne 0 -a $ENDVAL -gt 0 ] ; then
	    #-- for some weird cases (run is finihed but with error code)
	    echo 'finished with error (run:' $RETVAL ' end:' $ENDVAL ')'
	    printf '=> output from running in %s :\n' $1 1>&2
	    tail $RUNLOG | sed 's/^.*/> &/g' 1>&2
	    return 0
	else
	    echo 'failed (run:' $RETVAL ' end:' $ENDVAL ')'
	    printf '=> output from running in %s :\n' $1 1>&2
	    tail $RUNLOG | sed 's/^.*/> &/g' 1>&2
	    cp $RUNLOG $CDIR"/"$RUNLOG
	    return 1
	fi
    )
}

createcodelet()
{
    # create codelet for comparing model output

    printf "creating the comparison code (using CC=$CC)...  "
    cat > tr_cmpnum.c <<EOF
#include <stdio.h>
#include <math.h>
int main( int argc, char** argv )  {
  int linnum,cmplin,best,lncnt;
  double a,b,abave,relerr;
  best = -22;
  lncnt = 0;
  while( 1 & ( (lncnt+=1) < 999 ) )  {
    scanf("%d", &linnum);
    if (linnum == -1)  break;
    scanf("%lf", &a);  scanf("%lf", &b);
    abave = 0.5*(fabs(a)+fabs(b));
    if ( abave == abave ) {
      if (abave > 0.0) {
        relerr=fabs(a-b)/abave;
        if (relerr > 0.0) { cmplin = (int)rint(log10(relerr)); }
        else { cmplin = -16 ; }
        best = (best > cmplin) ? best : cmplin; }
      else { cmplin = -22 ; }
   /* printf("%d ; %lf ; %lf\n",cmplin,a,b); */
      }
   else {
   /* printf("%lf ; %lf ; %lf\n",abave,a,b); */
      break; }
  }
  if (lncnt == 999) best=-29;
  if (linnum != -1) best=-99;
  printf("%d\n", -best);
  return 0;
}
EOF
    $CC -o tr_cmpnum tr_cmpnum.c -lm

    if [ -x ./tr_cmpnum ]; then
	echo "OK"
	return 0
    else
	echo
	echo "ERROR: failed to compile comparison code -- please specify"
	echo "  a C compiler using the CC environment variable."
	exit 1
    fi
}

formatresults()
{
    # formatresults expt genmake depend make run results*

    nm=$1
    printf '%s %s %s %s' $2 $3 $4 $5
    shift; shift; shift; shift; shift;
    listPrt=$@
    listRes=`echo $listPrt | sed 's/>//' | sed 's/<//'`
    xx=`echo $listPrt | sed 's/.*>//' | sed 's/<.*//' | awk '{print $1}'`
    printf '%3s' $listPrt
#   line below does not work on hp-ux_ia64 : do those substitutions later on
#   printf '%3s' $listPrt | sed 's/ 99/ --/g' | sed 's/  > />/' | sed 's/  < /</'

    if [ $xx = '..' ]; then
	printf ' N/O '
    elif [ $xx = '--' ]; then
	printf ' N/O '
    elif [ $xx = 99 ]; then
	printf ' N/O '
    else
	if [ $xx -ge $MATCH_CRIT ]; then
	    printf ' pass'
	else
	    printf ' FAIL'
	fi
    fi
    printf '  %s' $nm
    if test $KIND = 2 ; then
	#-- append taf report summary:
	tafrep=`grep -c '^ TAF reports ' $CDIR/summary.txt`
	if test $tafrep = 1 ; then
	    grep '^ TAF reports ' $CDIR/summary.txt | awk '{printf "  (e=%i, w=%i,",$3,$6}'
	    grep '^ load_fields_driver,' $CDIR/summary.txt \
		| awk '{printf " lfd=%i, dop=%i, sm=%i)",$7,$9,$11}'
	fi
    fi
    printf '\n'

}

scandirs()
{
    if [ $# -eq 1 ]; then
 	for arg in * ; do
 	   #test -f $arg/$1 && echo $arg
 	    test -f $arg/$1 -o -f $arg/$1.gz && echo $arg
 	done
    else
 	echo $*
    fi
}

check_eedata()
{
    # check_eedata eedata size.h
    if [ $# -eq 2 ] ; then
     if test -f $1 -a -f $2 ; then
      nx=`grep "^ *nTx *=" $1 | tail -1 | sed 's/^ *nTx *= *//' | sed "s/, *$//"`
      sx=`grep "^     & *nSx *=" $2 | sed "s/^     & *nSx *=//" | sed 's/, *$//'`
      if test "x$nx" = x ; then
	rx=10
      else
	rx=`expr $sx % $nx`
      fi
      ny=`grep "^ *nTy *=" $1 | tail -1 | sed 's/^ *nTy *= *//' | sed "s/, *$//"`
      sy=`grep "^     & *nSy *=" $2 | sed "s/^     & *nSy *=//" | sed 's/, *$//'`
      if test "x$ny" = x ; then
	ry=20
      else
	ry=`expr $sy % $ny`
      fi
      echo `expr $rx + $ry`
     else
      echo '-1'
     fi
    elif [ $# -eq 1 ] ; then
     if test -f $1 ; then
      nx=`grep "^ *nTx *=" $1 | tail -1 | sed 's/^ *nTx *= *//' | sed "s/, *$//"`
      if test "x$nx" = x ; then nx=1 ; fi
      ny=`grep "^ *nTy *=" $1 | tail -1 | sed 's/^ *nTy *= *//' | sed "s/, *$//"`
      if test "x$ny" = x ; then ny=1 ; fi
     #echo $nx $ny
      echo $nx
     else
      echo '-1'
     fi
    else
      echo '-2'
    fi

}

###############################################################################

#  Default properties
debug=0
verbose=1
NBLINES_MKLOG=16000

OptLev=1
GSL=f

CLEANUP=f
NORUN=f
QUICK=f
NOMAKE=f
NOGENMAKE=f
NOCLEAN=f
NODEPEND=f
POSTCLEAN=0

BASH=
OPTFILE=NONE
ADDRESSES=
TESTDIRS=
SKIPDIRS=
MPACKDIR="../tools/mpack-1.6"
HAVE_MPACK=
MPACK=
SENDCMD=
SAVDIR='.'
COMMAND=
MKDEPEND=
if test "x$MAKE" = x ; then
    MAKE=make
fi
MAKE_CMD=
if test "x$CC" = x ; then
    CC=cc
fi
JOBS=
TARG=
MPI=0
MPI_MFILE=
MULTI_THREAD=f
OUTDIR=
DELDIR=
USE_R4=
EXTRFLG=
NOCATAD=
MKSMALLF=
OADSINGULARITY=
CHECK_PASS=f

#- type of testing (KIND):
#   KIND=0 : forward (= default) ;     KIND=6 : Adjoint with OpenAD
#   KIND=1 : Tangent-Linear with TAF ; KIND=2 : Adjoint with TAF ;
#   KIND=4 : Tang-Lin. with Tapenade ; KIND=5 : Adjoint with Tapenade ;
KIND=0

# list of pTracers to check for monitor output
PTRACERS_NUM="1 2 3 4 5"

MATCH_CRIT=10

printf "parsing options...  "

ac_prev=
for ac_option ; do

    # If the previous option needs an argument, assign it.
    if test -n "$ac_prev"; then
        eval "$ac_prev=\$ac_option"
        ac_prev=
        continue
    fi

    ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`

    case $ac_option in

	-help | --help | -h | --h) usage ;;

	-optfile | --optfile | -of | --of) ac_prev=OPTFILE ;;
	-optfile=* | --optfile=* | -of=* | --of=*) OPTFILE=$ac_optarg ;;

	-addr | --addr | -a | --a) ac_prev=ADDRESSES ;;
	-addr=* | --addr=* | -a=* | --a=*) ADDRESSES=$ac_optarg ;;
	-mpackdir | --mpackdir | -mpd | --mpd) ac_prev=MPACKDIR ;;
	-mpackdir=* | --mpackdir=* | -mpd=* | --mpd=*) MPACKDIR=$ac_optarg ;;

	-send | --send ) ac_prev=SENDCMD ;;
	-send=* | --send=* ) SENDCMD=$ac_optarg ;;
	-savdir | --savdir | -sd | --sd ) ac_prev=SAVDIR ;;
	-savdir=* | --savdir=* | -sd=* | --sd=* ) SAVDIR=$ac_optarg ;;

	-tdir | --tdir | -t | --t) ac_prev=TESTDIRS ;;
	-tdir=* | --tdir=* | -t=* | --t=*) TESTDIRS=$ac_optarg ;;
	-skipdir | --skipdir | -skd | --skd) ac_prev=SKIPDIRS ;;
	-skipdir=* | --skipdir=* | -skd=* | --skd=*) SKIPDIRS=$ac_optarg ;;

	-bash | --bash | -b | --b) ac_prev=BASH ;;
	-bash=* | --bash=* | -b=* | --b=*) BASH=$ac_optarg ;;

	-command | --command | -c | --c) ac_prev=COMMAND ;;
	-command=* | --command=* | -c=* | --c=*) COMMAND=$ac_optarg ;;

	-makedepend | --makedepend | -md | --md) ac_prev=MKDEPEND ;;
	-makedepend=* | --makedepend=* | -md=* | --md=*) MKDEPEND=$ac_optarg ;;

	-make | --make | -m | --m) ac_prev=MAKE ;;
	-make=* | --make=* | -m=* | --m=*) MAKE=$ac_optarg ;;

	-repl_mk | --repl_mk ) ac_prev=MAKE_CMD ;;
	-repl_mk=* | --repl_mk=*) MAKE_CMD=$ac_optarg ;;

	-odir | --odir) ac_prev=OUTDIR ;;
	-odir=* | --odir=*) OUTDIR=$ac_optarg ;;

	-ptracers | --ptracers | -ptr | --ptr) ac_prev=PTRACERS_NUM ;;
	-ptracers=* | --ptracers=* | -ptr=* | --ptr=*) PTRACERS_NUM=$ac_optarg ;;

	-match | --match ) ac_prev=MATCH_CRIT ;;
	-match=* | --match=* ) MATCH_CRIT=$ac_optarg ;;

	-j | --j) ac_prev=JOBS ;;
	-j=* | --j=*) JOBS=$ac_optarg ;;

	-ef | --ef) ac_prev=EXTRFLG ;;
	-ef=* | --ef=*) EXTRFLG=$ac_optarg ;;

	-clean | --clean) CLEANUP=t ; DELDIR=t ;;

	-norun | --norun | -nr | --nr) NORUN=t ;;
	-obj | --obj ) TARG='obj' ; NORUN=t ;;
	-src | --src ) TARG='small_f' ; NORUN=t ;;
	-runonly | --runonly | -ro | --ro) QUICK=t ; NOMAKE=t ;;
	-quick | --quick | -q | --q) QUICK=t ;;
	-nogenmake | --nogenmake | -ng | --ng) NOGENMAKE=t ;;
	-noclean | --noclean | -nc | --nc) NOCLEAN=t ;;
	-nodepend | --nodepend | -nd | --nd) NODEPEND=t ;;

	-postclean | --postclean | -pc | --pc) POSTCLEAN=2 ;;
	-deloutp | --deloutp | -do | --do) POSTCLEAN=1 ;;

	-pass) CHECK_PASS=t ;;

	-mpi | --mpi) MPI=2 ;;
	-MPI | --MPI) ac_prev=MPI ;;
	-MPI=* | --MPI=*) MPI=$ac_optarg ;;

	-mfile | --mfile | -mf | --mf) ac_prev=MPI_MFILE ;;
	-mfile=* | --mfile=* | -mf=* | --mf=*) MPI_MFILE=$ac_optarg ;;

	-mth) MULTI_THREAD=t ;;

	-tlm) if test $KIND = 0 -o $KIND = 3 ; then KIND=`expr $KIND + 1`; else
		echo "Error: '-tlm', '-adm' and '-oad' are exclusive + no duplicate" ; usage
	      fi ;;
	-adm | -ad) if test $KIND = 0 -o $KIND = 3 ; then KIND=`expr $KIND + 2` ; else
		echo "Error: '-tlm', '-adm' and '-oad' are exclusive + no duplicate" ; usage
	      fi ;;
	-tap) if [ $KIND -le 2 ] ; then KIND=`expr $KIND + 3` ; else
		echo "Error: '-tap' and '-oad' are exclusive + no duplicate" ; usage
	      fi ;;
	-oad) if test $KIND = 0 ; then KIND=6 ; NODEPEND=t ; else
		echo "Error: '-tlm', '-adm' and '-oad' are exclusive + no duplicate" ; usage
	      fi ;;
	-oadsingularity | --oadsingularity | -oadsngl | --oadsngl) ac_prev=OADSINGULARITY ;;
	-oadsingularity=* | --oadsingularity=* | -oadsngl=* | --oadsngl=*) OADSINGULARITY=$ac_optarg ;;

	-ncad) NOCATAD=t ;;
	-small_f) MKSMALLF=t ;;

	-ieee)   echo "Warning: ignore option '-ieee' (already the default)"
		 printf " ... " ;;
	-noieee) echo "Warning: will use option '-fast' instead of '-noieee' (obsolete)"
		 printf " ... " ; OptLev=`expr $OptLev \* 2` ;;
	-fast)  OptLev=`expr $OptLev \* 2` ;;
	-devel) OptLev=0 ;;
	-gsl) GSL=t ;;

	-verbose) verbose=2 ;;
	-debug) debug=1 ;;
	-quiet) verbose=0 ;;

	-deldir | -dd) DELDIR=t ;;

	-use_r4|-ur4) USE_R4=t ;;

	-ts) TS=t;;
	-papis) PAPIS=t;;
	-pcls) PCLS=t;;

	-*) echo "Error: unrecognized option: "$ac_option
	    usage ;;
	*)  echo "Error: unrecognized argument: "$ac_option
	    usage ;;

     esac

done

if test "x$QUICK" = xt ; then
    NOGENMAKE=t
    NOCLEAN=t
    NODEPEND=t
fi
if test "x$MAKE_CMD" = x ; then MAKE_CMD=$MAKE ; fi

#- check length of MPI machine file:
if test "x$MPI" != x0 -a "x$MPI_MFILE" != x ; then
    if test -r $MPI_MFILE ; then
	nl=`wc -l $MPI_MFILE | awk '{print $1}'`
	if [ $nl -lt $MPI ] ; then
	  echo "Error: need at least $MPI nodes (currently only $nl) in MPI_MFILE=$MPI_FILE"
	  usage
	fi
	if [ $verbose -gt 1 ]; then
	    echo " MPI_MFILE=$MPI_MFILE : $nl procs for MPI=$MPI run"
	fi
    else
	  echo "Error: cannot access MPI_MFILE=$MPI_FILE"
	  usage
    fi
fi

#- setting for forward, TLM or ADM testing
if test $KIND = 1 ; then
    if test "x$TARG" = x        ; then TARG=ftlall ; fi
    if test "x$TARG" = xobj     ; then TARG=ftlobj ; fi
    if test "x$TARG" = xsmall_f ; then TARG=ftltaf ; fi
    code_dir=code_ad
    inputdir=input_ad
    ref_outp="output_tlm.txt"
    EXECUTABLE="mitgcmuv_ftl"
elif test $KIND = 2 ; then
    if test "x$TARG" = x        ; then TARG=adall ; fi
    if test "x$TARG" = xobj     ; then TARG=adobj ; fi
    if test "x$TARG" = xsmall_f ; then TARG=adtaf ; fi
    code_dir=code_ad
    inputdir=input_ad
    ref_outp="output_adm.txt"
    EXECUTABLE="mitgcmuv_ad"
elif test $KIND = 4 -o $KIND = 5 ; then
    if test $KIND = 4 ; then TARG=tap_tlm ; else TARG=tap_adj ; fi
    code_dir=code_tap
    inputdir=input_tap
    ref_outp="output_${TARG}.txt"
    EXECUTABLE="mitgcmuv_${TARG}"
elif test $KIND = 6 ; then
    TARG=adAll
    code_dir=code_oad
    inputdir=input_oad
    ref_outp="output_oadm.txt"
    EXECUTABLE="mitgcmuv_ad"
else
    code_dir=code
    inputdir=input
    ref_outp="output.txt"
    EXECUTABLE="mitgcmuv"
fi
if test "x$JOBS" != x ; then TARG="-j $JOBS $TARG" ; fi

if [ $verbose -gt 1 ]; then
    echo ""
    echo "--- print $0 setting:"
    echo " KIND     =  '$KIND'"
    echo " TARG     =  '$TARG'"
    echo " code_dir =  '$code_dir'"
    echo " inputdir =  '$inputdir'"
    echo " ref_outp =  '$ref_outp'"
    echo " EXECUTABLE= '$EXECUTABLE'"
    echo "--- printing ends."
   #exit 0
fi

xx=`echo $TESTDIRS | awk '{print $1}'`
if test "x$TESTDIRS" = x ; then
    LIST=`scandirs results/$ref_outp`
elif test $xx = 'start_from' ; then
    xx=`echo $TESTDIRS | awk '{print $2}'`
    LIST=`scandirs results/$ref_outp | sed -n "/$xx/,$ p"`
else
    #- expand group of experiments:
    LIST=" "
    for xx in $TESTDIRS
    do
      case $xx in
	'basic') LIST=${LIST}" aim.5l_cs hs94.128x64x5 ideal_2D_oce"
		 LIST=${LIST}" lab_sea tutorial_baroclinic_gyre"
		 LIST=${LIST}" tutorial_global_oce_latlon tutorial_plume_on_slope"
		;;
	'tutorials')
		 LIST=${LIST}" "`ls | grep 'tutorial_'` ;;
	*)	 LIST=${LIST}" "$xx ;;
      esac
    done
fi
#echo 'LIST='${LIST}'<'
#- skip dirs, remove duplicate and non-directory:
TESTDIRS=" "
count=0
for xx in $LIST
do
    yy=`echo $SKIPDIRS | grep -c $xx`
    if test $yy = 0 ; then
	if test -d $xx ; then
	    yy=`echo $TESTDIRS | grep -c $xx`
	    if test $yy = 0 ; then TESTDIRS=${TESTDIRS}" "$xx ; fi
	else count=1 ;
	    echo ""; echo -n " -- skip \"$xx\" (not a directory !)"
	fi
    else
	if test $count = 1 ; then echo -n ", \"$xx\""
	else count=1 ; echo "" ;  echo -n " skip: \"$xx\""
	fi
    fi
done
if test $count = 1 ; then echo "" ; echo -n " ... " ; fi
#echo 'TESTDIRS='${TESTDIRS}'<'

LOC_MFILE='mpi_mfile.loc'
RUNLOG="run.tr_log"
if test "x$MPI" = x0 ; then
  OUTPUTFILE=$ref_outp
  if test "x$COMMAND" = x ; then COMMAND="./$EXECUTABLE > $OUTPUTFILE" ; fi
else
  OUTPUTFILE="STDOUT.0000"
  if test "x$COMMAND" = x ; then COMMAND="mpirun -np TR_NPROC ./$EXECUTABLE" ; fi
fi

echo "OK (COMMAND='$COMMAND')"

#TMP=./tr_$$
#- try to put temporary files in system-local /tmp dir
TMP=/tmp/tr_${USER}_$$
touch $TMP ; retVal=$?
if [ $retVal -eq 0 ] ; then
  if test ! -r $TMP ; then TMP=./tr_$$ ; fi
else
  TMP=./tr_$$
fi
rm -f $TMP
if [ $verbose -gt 1 ]; then echo " temp files: $TMP" ; fi

# set the Default List of output variables to be checked:
#  (use default or load experiment-specific list from file "tr_checklist")
# content : 1rst = main variable used to decide if it pass or FAIL
#         others = number of matching digits to be printed in summary.txt
if test $KIND = 0 ; then
    DEF_CHECK_LIST='PS PS T+ S+ U+ V+ pt1+ pt2+ pt3+ pt4+ pt5+'
    EMPTY_RESULTS='.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..'
    LEN_CHECK_LIST=`echo $DEF_CHECK_LIST | sed 's/ [a-zA-Z0-9]*+/&mn &mx &av &sd/g' | awk '{print NF-1}'`
    ii=`echo $EMPTY_RESULTS | awk '{print NF}'`
    EMPTY_RESULTS=$EMPTY_RESULTS`expr $LEN_CHECK_LIST - $ii | awk 'BEGIN{FS=":"}{for(i=1;i<=$1;i++){printf "  ."}}'`
elif test $KIND = 2 ; then
    DEF_CHECK_LIST='admGrd admCst admGrd admFwd T+ S+ U+ V+'
    EMPTY_RESULTS='.. .. .. .. .. .. ..  .. .. .. ..  .. .. .. ..  .. .. .. ..'
    LEN_CHECK_LIST=`echo $DEF_CHECK_LIST | sed 's/ [a-zA-Z0-9]*+/&mn &mx &av &sd/g' | awk '{print NF-1}'`
else
    DEF_CHECK_LIST='admGrd admCst admGrd admFwd'
    EMPTY_RESULTS='.. .. ..'
    LEN_CHECK_LIST=`echo $DEF_CHECK_LIST | sed 's/ [a-zA-Z0-9]*+/&mn &mx &av &sd/g' | awk '{print NF-1}'`
fi

#  create the FORTRAN comparison code
if test "x$CLEANUP" = xt -o -x tr_cmpnum ; then
    echo "skipping comparison code build"
else
    createcodelet
fi

#  build the mpack utility (if ADDRESSES = NONE, do it to test the build)
if test "x$ADDRESSES" = x -o "x$SENDCMD" != x ; then
    echo "skipping mpack build"
else
    build_mpack
    if test "x$HAVE_MPACK" = xt ; then SENDCMD=$MPACK ; fi
fi

#  Create a uniquely named directory to store results
CMDLINE=$0
for xx in "$@" ; do nw=`echo $xx | wc -w`
    if test $nw = '1' ; then CMDLINE="$CMDLINE $xx" ; else
      nb=`echo $xx | grep -c '='`
      if test $nb = 0 ; then CMDLINE="$CMDLINE '$xx'"
      else yy=`echo "$xx'" | sed "s/=/='/"` ;
			     CMDLINE="$CMDLINE $yy" ; fi
    fi
done
MACH=`hostname`
UNAMEA=`uname -a`
DATE=`date +%Y%m%d`
BASE="tr_"$MACH"_"$DATE"_"
if test "x$OUTDIR" != x ; then
    BASE="tr_"$OUTDIR"_"$DATE"_"
else
   #short_name=`hostname -s | tr '[:upper:]' '[:lower:]'`
   # hostname -s is not universal (does work on AIX system)
    short_name=`hostname | sed 's/\..*$//' | tr '[:upper:]' '[:lower:]'`
    BASE="tr_"$short_name"_"$DATE"_"
fi
DNUM=0
DRESULTS="$BASE$DNUM"
while test -e $DRESULTS ; do
    DNUM=$(( $DNUM + 1 ))
    DRESULTS="$BASE$DNUM"
done
mkdir $DRESULTS
RETVAL=$?
if test "x$RETVAL" != x0 ; then
    echo "ERROR: Can't create results directory \"./$DRESULTS\""
    exit 1
fi
SUMMARY="$DRESULTS/summary.txt"
start_date=`date`
echo $start_date > $SUMMARY
echo 'run:' $CMDLINE >> $SUMMARY
echo 'on :' $UNAMEA  >> $SUMMARY

of_path=
if test "x$OPTFILE" != xNONE ; then
    if test -r $OPTFILE ; then
	# get the path
	path=${OPTFILE%/*}
	if test "x$path" = x ; then
	    of_path=`pwd`
	else
	    of_path=`( cd $path > /dev/null 2>&1 ; pwd )`
	fi
	file=${OPTFILE##*/}
	OPTFILE=$of_path/$file
	cp $OPTFILE $DRESULTS
	echo >> $SUMMARY
	echo "  OPTFILE=$OPTFILE" >> $SUMMARY
    else
	echo | tee -a $SUMMARY
	echo "ERROR: can't read OPTFILE=\"$OPTFILE\"" | tee -a $SUMMARY
	exit 1
    fi
else
    echo >> $SUMMARY
    echo "No \"OPTFILE\" was specified ; genmake2 found and uses:" >> $SUMMARY
    #-note: to be filled later after 1rst run
fi
echo
echo >> $SUMMARY
if test $KIND = 0 ; then
    line_0=`printf '%s %2i' 'default' $MATCH_CRIT`
       line_0="$line_0  ----T-----  ----S-----  ----U-----  ----V-----"
    line_1="G D M    c        m  s        m  s        m  s        m  s"
    line_2="e p a R  g  m  m  e  .  m  m  e  .  m  m  e  .  m  m  e  ."
    line_3="n n k u  2  i  a  a  d  i  a  a  d  i  a  a  d  i  a  a  d"
    line_4="2 d e n  d  n  x  n  .  n  x  n  .  n  x  n  .  n  x  n  ."
    for ii in $PTRACERS_NUM ; do
	line_0="$line_0  --PTR 0"$ii"--"
	line_1="$line_1        m  s"
	line_2="$line_2  m  m  e  ."
	line_3="$line_3  i  a  a  d"
	line_4="$line_4  n  x  n  ."
    done
else
  if test $KIND = 1 ; then
    echo "TangLin generated by TAF" >> $SUMMARY
  elif test $KIND = 2 ; then
    echo "Adjoint generated by TAF" >> $SUMMARY
  elif test $KIND = 4 ; then
    echo "TangLin generated by Tapenade" >> $SUMMARY
  elif test $KIND = 5 ; then
    echo "Adjoint generated by Tapenade" >> $SUMMARY
  else
    echo "Adjoint generated by OpenAD" >> $SUMMARY
  fi
    line_0=`printf '%s %2i' 'default   ' $MATCH_CRIT`
  if test $KIND = 1 -o $KIND = 4 ; then
    line_1="G D M    C  T  F"
    line_2="e p a R  o  L  D"
  else
    line_1="G D M    C  A  F"
    line_2="e p a R  o  d  D"
  fi
    line_3="n n k u  s  G  G"
    line_4="2 d e n  t  r  r"
    echo >> $SUMMARY
  if test $KIND = 2 ; then
    line_0=`printf '%s %2i   ' 'default   ' $MATCH_CRIT`
    line_0="$line_0  ----T-----  ----S-----  ----U-----  ----V-----"
    line_1="$line_1        m  s        m  s        m  s        m  s"
    line_2="$line_2  m  m  e  .  m  m  e  .  m  m  e  .  m  m  e  ."
    line_3="$line_3  i  a  a  d  i  a  a  d  i  a  a  d  i  a  a  d"
    line_4="$line_4  n  x  n  .  n  x  n  .  n  x  n  .  n  x  n  ."
  fi
fi
if test "x$CLEANUP" != xt ; then
    echo "$line_0" | tee -a $SUMMARY
    echo "$line_1" | tee -a $SUMMARY
    echo "$line_2" | tee -a $SUMMARY
    echo "$line_3" | tee -a $SUMMARY
    echo "$line_4" | tee -a $SUMMARY
    echo ""        | tee -a $SUMMARY
fi
echo "-------------------------------------------------------------------------------"

allpass=t

#  ...and each test directory...
for dir in $TESTDIRS ; do

    # set builddir & rundir:
    builddir="build"
    if test ! -d $dir/$builddir ; then mkdir $dir/$builddir ; fi
    rundir="run"
    pfxdir="tr_$rundir"
    if test ! -d $dir/$rundir ; then
	rundir=$builddir
    fi
    CODE_DIR=$dir/$code_dir
    BUILD_DIR=$dir/$builddir

    #  Cleanup only!
    if test "x$CLEANUP" = xt ; then
	echo -n '  --- dir:' $BUILD_DIR ': '
	makeclean $BUILD_DIR
	(   cd $BUILD_DIR
	    rm -f $EXECUTABLE *.bak
	    rm -f genmake_state genmake_*optfile genmake.log
	    rm -f SIZE.h.mpi genmake.tr_log make.tr_log
	    rm -rf mpi_headers
	)
	if test -d $dir/$rundir ; then
	    echo -n '  --- dir:' $dir/$rundir ': '
	    run_clean $dir/$rundir
	fi
	trdir=`( cd $dir ; find . -type d -name "$pfxdir.*" -print | sed 's/^.\///')`
	ttd=`echo $trdir | wc -w`
	if test $ttd != 0 ; then
	    echo '  --- rm dir:' $trdir
	    ( cd $dir ; rm -rf $trdir )
	fi
	continue
    fi

    #  Verify that the testdir exists and contains previous
    #  results in the correct location--or skip this directory!
    fout=$dir"/results/"$ref_outp
   #if test ! -r $fout ; then
    if test ! -r $fout -a ! -r ${fout}.gz ; then
	echo "can't read \"$fout\" -- skipping $dir"
	continue
    fi

    # Check for specific files for particular type of run

    if test ! -r $CODE_DIR"/SIZE.h_mpi"  -a "x$MPI" != "x0" ; then
	echo "can't find \"$CODE_DIR/SIZE.h_mpi\" -- skipping $dir"
	continue
    fi
    if test ! -r $dir"/input/eedata.mth" -a "x$MULTI_THREAD" = "xt" ; then
	echo "can't find \"$dir/input/eedata.mth\" -- skipping $dir"
	continue
    fi

    if test "x$MPI" = "x0" ; then
	LOC_NPROC=1
    else
	ntx=1 ; nty=1
	if test "x$MULTI_THREAD" = "xt" ; then
	  ff=$dir"/input/eedata.mth"
	  ntx=`grep "^ *nTx *=" $ff | tail -1 | sed 's/^ *nTx *= *//' | sed "s/, *$//"`
	  nty=`grep "^ *nTy *=" $ff | tail -1 | sed 's/^ *nTy *= *//' | sed "s/, *$//"`
	  if test "x$ntx" = x ; then ntx=1 ; fi
	  if test "x$nty" = x ; then nty=1 ; fi
	fi
	#- create new SIZE.h with no more than '$MPI' Procs
	mk_mpi_size $CODE_DIR"/SIZE.h_mpi" $BUILD_DIR"/tr_size.mpi" $MPI $ntx $nty
	LOC_NPROC=$?
	(   cd $BUILD_DIR
	    if test -r SIZE.h.mpi ; then
		cmp tr_size.mpi SIZE.h.mpi > /dev/null 2>&1 ; RETVAL=$?
	    else RETVAL=1
	    fi
	    if test "x$RETVAL" = x0 ; then
		rm -f tr_size.mpi
	    else
		rm -f SIZE.h.mpi ; mv tr_size.mpi SIZE.h.mpi
	    fi
	)
	if test "x$MPI_MFILE" != x ; then
	    #- create new MPI machine-file with the right number of Procs
	    rm -f $dir/$LOC_MFILE
	    cat $MPI_MFILE | sort | uniq | head -$LOC_NPROC > $dir/$LOC_MFILE
	    nl=`wc -l $dir/$LOC_MFILE | awk '{print $1}'`
	    if [ $nl -lt $LOC_NPROC ] ; then
		rm -f $dir/$LOC_MFILE
		cat $MPI_MFILE | head -$LOC_NPROC > $dir/$LOC_MFILE
		#sed -n "1,$LOC_NPROC p" $MPI_MFILE > $dir/$LOC_MFILE
	    fi
	    if [ $verbose -gt 1 ]; then
		nl=`wc -l $LOC_MFILE | awk '{print $1}'`
		echo " new LOC_MFILE=$dir/$LOC_MFILE : $nl procs for LOC_NPROC=$LOC_NPROC"
	    fi
	fi
	if test "x$MULTI_THREAD" = "xt" ; then
	    retv=`check_eedata $dir"/input/eedata.mth" $BUILD_DIR"/SIZE.h.mpi"`
	    if test $retv != 0 ; then
		echo "input/eedata.mth tiling misfit -- skipping $dir"
		continue
	    fi
	fi
    fi

    #  Check whether there are "extra runs" for this testdir
    extra_runs=
    if test "x$NORUN" = xf ; then
	ex_run_dirs=`( cd $dir ; ls -d $inputdir.* 2> /dev/null )`
    fi
    #echo "ex_run_dirs='$ex_run_dirs'"
    for exd in $ex_run_dirs ; do
	name=`echo $exd | sed -e "s/$inputdir\.//"`
	refExOut=`echo $ref_outp | sed "s/\./.${name}./"`
	outf="$dir/results/$refExOut"
	if test -r $outf -o -r ${outf}.gz ; then
	  if test "x$MULTI_THREAD" = "xt" ; then
	    if test -r $dir"/"$exd"/eedata.mth" ; then
	      if test "x$MPI" = "x0" ; then
		extra_runs="$extra_runs $name"
	      else
		retv=`check_eedata $dir"/"$exd"/eedata.mth" $BUILD_DIR"/SIZE.h.mpi"`
		if test $retv = 0 ; then
		    extra_runs="$extra_runs $name"
		else
		    echo $exd"/eedata.mth tiling misfit -- skipping $dir"
		fi
	      fi
	    #else echo $dir"/"$exd"/eedata.mth: not found"
	    fi
	  else
	    extra_runs="$extra_runs $name"
	  fi
	fi
    done

    echo
    if test "x$extra_runs" = "x" ; then
	echo "Experiment:  $dir"
    else
	echo "Experiment:  $dir ; extra_runs=$extra_runs"
    fi
    echo
    unset genmake makedepend make run
    results=$EMPTY_RESULTS

    #  Create an output dir & summary.txt file for each tested experiment (tdir)
    locDIR=$DRESULTS"/"$dir
    mkdir $locDIR
    #- report to this experiment local summary file ---
    echo "DATE='$DATE' ; tdir='$dir'" > $locDIR"/summary.txt"
    echo "MACH='$MACH'" >> $locDIR"/summary.txt"
    echo "UNAMEA='$UNAMEA'" >> $locDIR"/summary.txt"
    CDIR=`pwd`"/$locDIR"

    if test "x$NORUN" = xt ; then
	    run=N
	genmakemodel $dir/$builddir && genmake=Y \
	    && makeclean $dir/$builddir \
	    && symlink_mpifiles $dir $code_dir $builddir \
	    && makedependmodel $dir/$builddir && makedepend=Y \
	    && makemodel $dir/$builddir && make=Y
	    echo
    else
	genmakemodel $dir/$builddir && genmake=Y \
	    && makeclean $dir/$builddir \
	    && symlink_mpifiles $dir $code_dir $builddir \
	    && makedependmodel $dir/$builddir && makedepend=Y \
	    && makemodel $dir/$builddir && make=Y \
	    && run_clean $dir/$rundir \
	    && linkdata $dir/$rundir $inputdir \
	    && runmodel $dir/$rundir && run=Y \
	    && results=`testoutput_run $dir $rundir $ref_outp`
	    echo 1>&2
    fi
    #echo "results='$results'"

	fres=`formatresults $dir ${genmake:-N} ${makedepend:-N} ${make:-N} ${run:-N} $results`
	echo "$fres" | sed 's/ 99/ --/g' | sed 's/  > />/' | sed 's/  < /</' >> $SUMMARY
	echo "fresults='$fres'" | sed 's/ 99/ --/g' >> $locDIR"/summary.txt"
        if [[ ! "$fres" =~ " pass " ]]; then
            allpass=f
        fi

	for ex in $extra_runs ; do
	    unset run
	    results=$EMPTY_RESULTS
	    #  reference output file
	    refExOut=`echo $ref_outp | sed "s/\./.${ex}./g"`
	    #  Create an output dir & summary.txt file for each extra run (tdir.ex)
	    locDIR=$DRESULTS"/"$dir"."$ex
	    mkdir $locDIR
	    #- report to this experiment local summary file ---
	    echo "DATE='$DATE' ; tdir='$dir.$ex'" > $locDIR"/summary.txt"
	    #echo "MACH='$MACH'" >> $locDIR"/summary.txt"
	    #echo "UNAMEA='$UNAMEA'" >> $locDIR"/summary.txt"
	    CDIR=`pwd`"/$locDIR"
	    test ! -e "$dir/$pfxdir.$ex" && mkdir "$dir/$pfxdir.$ex"
	    run_clean $dir/$pfxdir.$ex
	    linkdata $dir/$pfxdir.$ex $inputdir.$ex $inputdir
	    runmodel $dir/$pfxdir.$ex && run=Y \
	    && results=`testoutput_run $dir $pfxdir.$ex $refExOut`
	    echo 1>&2

	    fres=`formatresults $dir.$ex ${genmake:-N} ${makedepend:-N} ${make:-N} ${run:-N} $results`
	    echo "$fres" | sed 's/ 99/ --/g' | sed 's/  > />/' | sed 's/  < /</' >> $SUMMARY
	    echo "fresults='$fres'" | sed 's/ 99/ --/g' >> $locDIR"/summary.txt"
            if [[ ! "$fres" =~ " pass " ]]; then
                allpass=f
            fi
	    if test "x$POSTCLEAN" = x2 ; then
		run_clean $dir/$pfxdir.$ex
	    fi
	done

    if test ! -f $DRESULTS"/"genmake_state ; then
	if test -f $dir/$builddir/Makefile ; then
	    mkOpt=`grep '^# OPTFILE=' $dir/$builddir/Makefile 2>/dev/null | head -1 | sed 's/^# //'`
	    echo "from '$dir/$builddir/Makefile', extract:" > $DRESULTS/genmake_state
#	    sed -n '/^# executed by:/,+1 p' $dir/$builddir/Makefile >> $DRESULTS/genmake_state
# bsd-sed cannot do the above code
	    cat $dir/$builddir/Makefile | \
		sed -n '/^# executed by:/{N
                                          p
                                          }' >> $DRESULTS/genmake_state
	    echo " $mkOpt" >> $DRESULTS/genmake_state
	    if test "x$OPTFILE" = xNONE ; then
		eval $mkOpt
#		sed "/^No \"OPTFILE\" was specified ; genmake2/a\  OPTFILE=${OPTFILE}"\
#			$SUMMARY > tmp.tr_log
# bsd-sed requires a newline after "a\":
		sed "/^No \"OPTFILE\" was specified ; genmake2/a\\
                         OPTFILE=${OPTFILE}" $SUMMARY > tmp.tr_log
		RETVAL=$?
		if test "x$RETVAL" = x0 ; then
		    cp -f tmp.tr_log $SUMMARY
		fi
		rm -f tmp.tr_log
	    fi
	    gmkLog=$dir/$builddir/genmake.log
	    if test -r $gmkLog ; then
		grep '^Get compiler version using:' $gmkLog > /dev/null 2>&1
		RETVAL=$?
		if test "x$RETVAL" = x0 ; then
		  echo -n "from '$gmkLog', "	>> $DRESULTS/genmake_state
		  echo "extract compiler version:"   >> $DRESULTS/genmake_state
		  sed -n '/Get compiler version/,/<-- compiler version/p' \
		     $gmkLog | grep -v '^... compiler version ' > tmp.tr_log
		  sed -n '1p' tmp.tr_log	>> $DRESULTS/genmake_state
		  sed -n '2,/^$/p' tmp.tr_log | sed '/^$/d' | sed 's/^./ &/' \
						>> $DRESULTS/genmake_state
		  rm -f tmp.tr_log
		fi
		grep ' set FC_CHECK=' $gmkLog	>> $DRESULTS/genmake_state
	    fi
	    if test $KIND = 1 -o  $KIND = 2 ; then
	      gmkLog=$dir/$builddir/taf_ad.log
	      if test $KIND = 1 ; then gmkLog=$dir/$builddir/taf_ftl.log ; fi
	      if test -f $gmkLog ; then
		echo -n "from '$gmkLog', get: " >> $DRESULTS/genmake_state
		head -1 $gmkLog | sed 's/^.*Algorithms in Fortran //' \
						>> $DRESULTS/genmake_state
		ADvers=`head -1 $gmkLog | awk '{print $7,$8}'`
		sed "s/ by TAF/ by TAF $ADvers/" $SUMMARY > tmp.tr_log
		mv -f tmp.tr_log $SUMMARY
	      fi
	    fi
	    if test $KIND = 4 -o  $KIND = 5 ; then
	      gmkLog=$dir/$builddir/make.tr_log
	      if test -f $gmkLog ; then
		ADtool=`grep '^Tapenade ' $gmkLog | tail -n 1`
		echo "from '$gmkLog', get: $ADtool" >> $DRESULTS/genmake_state
		#ADvers=`echo $ADtool | awk '{print $2,$3}'`
		ADvers=`echo $ADtool | sed -e 's/^Tapenade //' -e 's/ [0-9]*:[0-9][0-9] .*$//'`
		sed "s/ by Tapenade/ by Tapenade $ADvers/" $SUMMARY > tmp.tr_log
		mv -f tmp.tr_log $SUMMARY
	      fi
	    fi
	    gmkLog=$dir/$builddir/genmake_state
	    if test -r $gmkLog ; then
		echo -n "from '$gmkLog', "	>> $DRESULTS/genmake_state
		echo "get genmake settings:"	>> $DRESULTS/genmake_state
		sed -n '/^HAVE_/p' $gmkLog | sed 's/^./ &/' \
						>> $DRESULTS/genmake_state
		sed -n '/^THIS[A-Z]*=/p' $gmkLog >> $DRESULTS/genmake_state
	    fi
	fi
    fi
    #postclean $dir/$builddir
    if test "x$POSTCLEAN" = x2 ; then
	makeclean $dir/$builddir \
	    && run_clean $dir/$rundir
    fi
    if test "x$MPI" != x0 -a "x$MPI_MFILE" != x ; then rm -f $dir/$LOC_MFILE ; fi

    echo "-------------------------------------------------------------------------------"

done
grep '^HAVE_LAPACK' */$builddir/genmake_state 2> /dev/null \
			| head -1 >> $DRESULTS/genmake_state

printf "Start time:  " >> $SUMMARY
echo "$start_date" >> $SUMMARY
printf "End time:    " >> $SUMMARY
date >> $SUMMARY

#  If addresses were supplied and mpack built successfully, then try
#  to send email using mpack.
if test "x$ADDRESSES" = xNONE -o "x$ADDRESSES" = x ; then
    echo "No results email was sent."
else
    if test "x$SENDCMD" != x ; then
	sendOpt='' ; nb=`echo $SENDCMD | grep -c '\<scp\>'`
	if [ $nb -eq 0 ] ; then
	   sendOpt='-s MITgcm-test -m 3555000'
	   tarFile="${SAVDIR}/${DRESULTS}.tar"
	else
	   tarFile="${SAVDIR}/${DRESULTS}.$$.tar"
	fi
	if [ $verbose -gt 1 ]; then
	   echo " run: $SENDCMD $sendOpt ${tarFile}.gz $ADDRESSES"
	fi
	tar -cf ${tarFile} $DRESULTS > /dev/null 2>&1 \
	    && gzip ${tarFile} \
	    && $SENDCMD $sendOpt ${tarFile}".gz" $ADDRESSES
	RETVAL=$?
	echo
	if test "x$RETVAL" != x0 ; then
	    echo "Warning: The tar, gzip, & $SENDCMD step failed.  Please send email"
	    echo "  to <MITgcm-support@mitgcm.org> for help.  You may copy the "
	    echo "  summary of results from the directory \"$DRESULTS\"."
	else
	    echo "An email containing results was sent to the following addresses:"
	    echo "  \"$ADDRESSES\""
	    test -f ${tarFile}      &&  rm -f ${tarFile}
	    test -f ${tarFile}".gz" &&  rm -f ${tarFile}".gz"
	fi
	echo
    fi
fi

if test "x$QUICK" = xf -a "x$NORUN" = xf ; then
    rm -f tr_cmpnum.c tr_cmpnum
fi

if test "x$CLEANUP" != xt ; then
    cat $SUMMARY | sed 's/ \.  \.  \.  \.  \.  \.  \.  \.  \.  \.  \.  \. //'
    if test -e tr_out.txt ; then
	mv tr_out.txt tr_out.txt.old
    fi
    cat $SUMMARY | sed '/^[YN] [YN] [YN] [YN]/ s/ \. //g' > tr_out.txt
fi

if test "x$DELDIR" = xt ; then
    rm -rf $DRESULTS
fi

if test "$CHECK_PASS" = t && test "$allpass" = f; then
    exit 1
fi

echo "======== End of testreport execution ========"
