#!/bin/bash

######################################################################
#  Configure file for ORAC6.0(beta) march 2016 			     #
#  Do not edit this file unless you know what you are doing. 	     #
# 
#  This configure should work on any reasonable unix platform.	     #
#  Minimum requirements for the default target are:		     #
#  bash, gmake, gfortran (4.7 up), gcc.  			     #
#  Supported Compilers are gfortran Intel PGI and xlf                #
# 
#  HPC specific compiler/linker options for OpenMP/MPI applications  #
#  are listed in the variables  OMPFLAGS F90FLAGS and OMPF.          #
######################################################################

function help_cnfg {
    echo " Usage: configure [options]                             ";
    echo "   valid Options are:                                   ";
    echo "                                                        ";
    echo "  --- Select compiler   ----                            ";
    echo "  -gfortran|-GNU                                        ";
    echo "  -Intel|-intel|-INTEL                                  ";
    echo "  -AIX|-aix|-IBM                                        ";
    echo "  -PGI|-pgi                                             ";
    echo "  -BGQ|-bgq-|-Fermi                                     ";
    echo "                                                        ";
    echo "  --- Target options ---    -                           ";
    echo "  -FFWT                  -> Use fftw3 library           ";
    echo "  -OMP|-omp|-OpenMP      -> Use OpenMP                  ";
    echo "  -MPI|-mpi|             -> Use MPI                     ";
    echo "  -DBG|-debug            -> compile with -g             ";
    echo "  -PROF|-prof            -> Profiling/testing           ";
    echo "  -CHECK|-check          -> Bound Checking              "
    echo "  -KNL|-knl              -> Compile for Intel Knight Landing       "
    echo "  -SKY|-sky              -> Compile for Intel Skylake              "
    echo "  -BDW|-bdw              -> Compile for Intel Broadwell            "
}

#
# Default Setting  
#

KNL="NO"
SKY="NO"
BDW="NO"
VEC="NO"
S_TARGET=GNU
S_FC=gfortran
S_LD=gfortran
S_FFLAGS=" "
S_CFLAGS=" "
S_FLAGSLD=" "
S_F90FLAGS=-O3 
S_FFTWOMPLIB=-lfftw3_threads
S_CPPARG=" "
S_OMPF=" "
S_SAVEF=" "
S_CC=gcc
S_MPIWRAP=mpif90
OMP="NO"
MPI="NO"
FFTW_PATH=-L
INC_FFTW_PATH=-I
DBGFLAGS="-g";
FFTW="NO"
DEBUG="NO"
PROF="NO"
COMP="UCKN"
PROFTYPE="PROF"

# check gfortran version
if [ -f `which gfortran` ] ; then
    gf_ver=`gfortran --version  | grep "GNU F" | awk '{print substr($NF,1,2)}' | sed "s/\.//g"`
    if [[ $gf_ver -gt 9 ]] ; then
	SF_ADD=" -fallow-argument-mismatch"
    else
	SF_ADD=""
    fi
fi

if [ $# -eq 0 ] ; then 
    S_FFLAGS="-ffree-line-length-0 $SF_ADD"
    S_CFLAGS=-DFC_UNDERSCORES;
    S_SAVEF=-fno-automatic;
else
    echo "Makefile generated with: " $0 $@
fi
#  Looping on options..
while :
do
    case "$1" in
#  Fortran compiler
    -gfortran|-GNU) COMP=GNU; 
	    echo  "COMPILER =     "$COMP; 
	    S_TARGET=GNU;
	    S_FC=gfortran;
	    S_LD=gfortran;
	    S_FFLAGS="$S_FFLAGS -ffree-line-length-0 $SF_ADD"
	    S_CFLAGS="$S_FCLAGS -DFC_UNDERSCORES";
	    S_FLAGSLD=$S_FLAGSLD; 
	    OMPFLAGS=-fopenmp;
	    DBGFLAGS="-g -fbacktrace"
            S_SAVEF=-fno-automatic;
	    S_MPIWRAP=mpif90; 
            S_F90FLAGS="$S_F90FLAGS" ;;
    -Intel|-INTEL|-intel)  COMP=ifort;
	    echo  "COMPILER =     "$COMP; 
	    S_TARGET=INTEL;
	    S_FC=ifort;
	    S_LD=ifort;
	    S_FFLAGS="$S_FFLAGS -132";
	    S_CFLAGS="$S_CFLAGS -DFC_UNDERSCORES";
	    S_FLAGSLD=$S_FLAGSLD;  
            S_F90FLAGS="-heap-arrays 2000" ;
	    PROFFLAGS="-prof-gen=srcpos"
	    KNLFLAGS="-xMIC-AVX512"
	    SKYFLAGS="-xCore-AVX512"
	    BDWFLAGS="-xCORE-AVX2"
	    PROFUSEFLAGS="-prof-use -ipo"
	    OMPFLAGS=-qopenmp;
	    DBGFLAGS="-g -traceback -debug all";
	    S_MPIWRAP=mpiifort; 
            S_SAVEF=-save;
	    S_CC=gcc;;
    -PGI|-pgi)    COMP=PGI ;
	    echo  "COMPILER =     "$COMP; 
	    S_TARGET=PGI;
	    S_FC=pgfortran;
	    S_LD=pgfortran;
	    S_FFLAGS="$S_FFLAGS -fast"
	    S_CFLAGS="$S_FCLAGS -DFC_UNDERSCORES";
	    S_FLAGSLD=$S_FLAGSLD;  
            S_F90FLAGS=-Mrecursive  ;
	    OMPFLAGS="-mp -Mrecursive" ;
	    PROFFLAGS="-fast -Minfo=ccff"
	    DBGFLAGS="-g -Mbounds -Mchkstk";
            S_SAVEF=-Msave;
	    S_CPPARG="$S_CPPARG -D_PGI_";
	    S_CC=pgcc;;
    -BGQ|-bgq|-Fermi)    COMP=BGQ;
	    echo  "COMPILER =     "$COMP; 
	    S_TARGET=BGQ;
	    S_FC=bgxlf90_r;
	    S_LD=bgxlf90_r;
	    S_FFLAGS="$S_FFLAGS -qinitauto -qstrict -qfixed=132 -qtune=auto -qarch=auto -qcache=auto";
	    S_CFLAGS="$S_CFLAGS";
	    S_FLAGSLD=$S_FLAGSLD;  
            S_F90FLAGS="$S_F90FLAGS -qfree -qsmallstack";  
	    OMPFLAGS="-qsmp=omp";
            S_SAVEF=-qsave;
	    S_CPPARG="$S_CPPARG -D_BGQ_ -DNO_SYS_CALLS";
	    S_CC=bgxlc_r;;
    -AIX|-aix|-IBM)    COMP=AIX;
	    echo  "COMPILER =     "$COMP; 
	    S_TARGET=AIX;
	    S_FC=xlf90_r;
	    S_LD=xlf90_r;
	    S_FFLAGS="$S_FFLAGS -qinitauto -qstrict -qfixed=132 -qtune=auto -qarch=auto -qcache=auto";
	    S_CFLAGS="$S_CFLAGS";
	    S_FLAGSLD=$S_FLAGSLD;  
            S_F90FLAGS="$S_F90FLAGS -qfree -qsmallstack";  
	    OMPFLAGS="-qsmp=omp";
            S_SAVEF="-qsave";
	    S_CPPARG="$S_CPPARG -D_BGQ_";
	    S_CC=xlc;
	    S_MPIWRAP=mpxlf90_r;; 
    -OMP|-omp|-OpenMP)    OMP="YES"; 
	    echo "OMP SUPPORT =  YES";;
    -MPI|-mpi)            MPI="YES";
	    echo "MPI SUPPORT =  YES";;
    -FFTW*|-fftw*)        FFTW="YES";
	    echo "FFTW SUPPORT = YES";
	    FFTW_PATH=$FFTW_PATH`echo $1 | awk '{a=substr($1,7); print a}'`; 
	    INC_FFTW_PATH=$INC_FFTW_PATH`echo $1 | awk '{a=substr($1,7); print a}'`; 
            if [ $FFTW_PATH != -L ]; then 
		S_FLAGSLD="$S_FLAGSLD $FFTW_PATH"/lib 
		S_FFLAGS="$S_FFLAGS $INC_FFTW_PATH"/include
		# Protect the innocent
		echo $S_FLAGSLD | sed "s/\//\\\\\//g" > xyz.0
		S_FLAGSLD=`cat xyz.0`
		echo $S_FFLAGS | sed "s/\//\\\\\//g" > xyz.0
		S_FFLAGS=`cat xyz.0`
		echo $S_FLAGSLD
		echo $S_FFLAGS
		rm xyz.0
	    fi 
	    S_FLAGSLD="$S_FLAGSLD -lfftw3";; 
    -PROF*|-prof*)        PROF="YES";
	    PROFTYPE=$1;
	    echo "PROFILING =    YES";;
    -DBG|-debug)        DEBUG="YES";
	    echo "DEBUG =        YES";;
    -CHECK|-check)      CHECK="YES";
	    echo "CHECK =        YES";;
    -KNL|-knl)      KNL="YES";
	    echo "KNL  =        YES";;
    -SKY|-sky)      SKY="YES";
	    echo "SKY  =        YES";;
    -BDW|-bdw)      BDW="YES";
	    echo "BDW  =        YES";;
    -VEC|-vec)      VEC="YES";
	    echo "VEC  =        YES";;
    -HELP|-help|-h)  help_cnfg;  exit ;; 
     -*) echo "???? bad argument $1";
	 echo ""; help_cnfg
	 exit ;;                                                          
    *) break;;
    esac
    shift
done

if [ $COMP == "UCKN" ]; then
    S_FFLAGS="$S_FFLAGS -ffree-line-length-0" # default is GNU compiler2
    S_CFLAGS="$S_CFLAGS -DFC_UNDERSCORES"  
    S_SAVEF=-fno-automatic;
    if [ $OMP == "YES" ] ; then
	OMPFLAGS="-fopenmp"
    fi
fi

# Setting precompilation flags
 
if [ $FFTW == "YES" ]; then 
    S_CPPARG="$S_CPPARG -DFFTW"
    S_TARGET="$S_TARGET-FFTW"
fi
if [ $OMP == "YES" ] ; then
    S_CPPARG="$S_CPPARG -D_OMP_"
    S_TARGET="$S_TARGET-OMP"
    S_OMPF=$OMPFLAGS
    S_FLAGSLD="$S_FLAGSLD $OMP_FLAGS"
    if [ $FFTW == "YES" ]; then 
	S_FLAGSLD="$S_FLAGSLD $OMP_FLAGS $S_FFTWOMPLIB"
    fi
fi

if [ $COMP == "ifort" ]; then
    if [[ $KNL  ==  "YES" ]] ; then 
	S_FFLAGS="$S_FFLAGS $KNLFLAGS"
    fi
    if [[ $SKY  ==  "YES" ]] ; then 
	S_FFLAGS="$S_FFLAGS $SKYFLAGS"
    fi
    if [[ $BDW  ==  "YES" ]] ; then 
	S_FFLAGS="$S_FFLAGS $BDWFLAGS"
    fi
fi

if [ $MPI == "YES" ]; then 
    S_CPPARG="$S_CPPARG -D_MPI_"
    S_TARGET="$S_TARGET-MPI"
    S_FC=$S_MPIWRAP
    S_LD=$S_MPIWRAP
    if [ $COMP == "ifort" ]; then
# -f90 option obsolete starting MPICH version 3.1, OMPI version 1.7
#   see discussion under at http://lists.mpich.org/pipermail/discuss/2013-December/001801.html
# also the wrapper's name has changed (now it's "mpifort", "mpif90" kept as a link to mpifort)
# 
##	S_FC="mpif90 -f90=ifort"
##	S_LD="mpif90 -f90=ifort"
	S_FC="mpiifort -fc=ifort -f90=ifort"
	S_LD="mpiifort -fc=ifort -f90=ifort" 
    fi
fi
if [ $KNL == "YES" ]; then 
    diffs=`cmp -s force_alchemy.f force_alchemy.KNL.f || echo "yes"`
    if [[ $diffs == "yes" ]] ; then 
	cp force_alchemy.KNL.f force_alchemy.f
    fi
else
    diffs=`cmp -s force_alchemy.f force_alchemy.BDWL.f || echo "yes"`
    if [[ $diffs == "yes" ]] ; then 
	cp force_alchemy.BDWL.f force_alchemy.f
    fi
fi

if [ $VEC == "YES" ]; then 
    diffs=`cmp -s force.f force.VEC.f || echo "yes"`
    if [[ $diffs == "yes" ]] ; then 
	cp force.VEC.f force.f
	cp mtsmd.VEC.f mtsmd.f
	cp mts_forces.VEC.f mts_forces.f
	cp run_minimize.VEC.f run_minize.f
    fi
else
    diffs=`cmp -s force_alchemy.f force_alchemy.BDWL.f || echo "yes"`
    if [[ $diffs == "yes" ]] ; then 
	cp force_alchemy.BDWL.f force_alchemy.f
    fi
fi

if [ $DEBUG == "YES" ]; then
    S_TARGET="$S_TARGET-DBG"
    S_FFLAGS="$S_FFLAGS $DBGFLAGS"
fi	 
    
if [ $PROF == "YES" ]; then
    S_TARGET="$S_TARGET-PROF"
    S_FFLAGS_SAVE=$S_FFLAGS
    S_FLAGSLD_SAVE=$S_FLAGSLD
    S_FFLAGS="$S_FFLAGS $PROFFLAGS"
    S_FLAGSLD="$S_FLAGSLD $PROFFLAGS"; 
    if [ $COMP == "ifort" ]; then   # reset target if ifort and report must be generated
	if [ $PROFTYPE == "-PROF2" -o  $PROFTYPE == "-prof2" ]; then
	    S_TARGET="$S_TARGET-PROF2"
	    PROFFLAGS=$PROFUSEFLAGS
	    S_FFLAGS="$S_FFLAGS_SAVE $PROFFLAGS"
	    S_FLAGSLD="$S_FLAGSLD_SAVE $PROFFLAGS"; 
    	else
	    function help_prf_int {
	    echo " "
	    echo " "
	    echo "******* PROFILING WITH INTEL REQUESTED *****************************"
	    echo "Current TARGET is " $S_TARGET
	    echo "Profiling with Ifort-Intel(TM)  include three phases:          "
	    echo " 1) Instrumentation compilation                                "
	    echo " 2) Instrumented execution "
	    echo " 3) Feedback compilation  "
	    echo " Phase 1"
	    echo "   compile the program with make cmd using this Makefile" 
	    echo " Phase 2 " 
	    echo "   run the executable generated in phase 1."
	    echo "   Choose a typical  input file for MD simulations."   
	    echo "   A .dyn file is generated in the target INTEL-PROF dir"
	    echo " Phase 3 "
            echo "   run ./configure -Intel -PROF2 generating a new Makefile;"
            echo "   issue a make cmd; this will created the INTEL-PROF-PROF2 dir;" 
	    echo "   Copy to that dir the .dyn file generated in phase 2 and"
	    echo "   and issue again a make cmd to generate the optimized target." 
	    echo "   cd into INTEL-PROF-PROF2 and run profmerge -dump to generate "
            echo "   the profiling report."  
	    echo "********************************************************************"
	    }
	fi
    fi	 
fi

# Printing out target SetUP

function log_cnfg {
echo "S_TARGET    =" $S_TARGET	  
echo "S_FC        =" $S_FC	  
echo "S_LD        =" $S_LD	  
echo "S_FFLAGS    =" $S_FFLAGS	  
echo "S_CFLAGS    =" $S_CFLAGS	  
echo "S_F90FLAGS  =" $S_F90FLAGS  
echo "S_FLAGSLD   =" $S_FLAGSLD	  
echo "S_CPPARG    =" $S_CPPARG	  
echo "S_OMPF      =" $S_OMPF	  
echo "S_SAVEF     =" $S_SAVEF     
echo "S_CC        =" $S_CC
echo "S_MPIWRAP   =" $S_MPIWRAP   
}    		 

log_cnfg; log_cnfg > config.log ; 

if [ $COMP == "ifort" ] ; then
    if [ $PROFTYPE == "-PROF" ]; then 
	help_prf_int; help_prf_int >> config.log;
    fi
fi 

sed "s/S\_FC/$S_FC/g" Makefile.in |\
sed "s/S\_CC/$S_CC/g" |\
sed "s/S\_LD/$S_LD/g" |\
sed "s/S\_FFLAGS/$S_FFLAGS/g" |\
sed "s/S\_CFLAGS/$S_CFLAGS/g" |\
sed "s/S\_F90FLAGS/$S_F90FLAGS/g" |\
sed "s/S\_FLAGSLD/$S_FLAGSLD/g" |\
sed "s/S\_FFTWOMPLIB/$S_FFTWOMPLIB/g" |\
sed "s/S\_CPPARG/$S_CPPARG/g" |\
sed "s/S\_OMPF/$S_OMPF/g" |\
sed "s/S\_SAVEF/$S_SAVEF/g" |\
sed "s/S\_TARGET/$S_TARGET/g" > Makefile  # Main Makefile

sed "s/S\_CC/$S_CC/g" libnblist/Makefile.in  > libnblist/Makefile #agbnp  
sed "s/S\_CC/$S_CC/g" libagbnp/Makefile.in  > libagbnp/Makefile   #agbnp

