1#!/usr/bin/env bash
2# script to download simint-generator, create the simint library, compile it
3# and link it in NWChem
4# FC=compilername can be used to set compiler, e.g.
5# SIMINT_MAXAM cane be used to set the maximum ang. momentum
6# FC=ifort ./build_simint.sh
7#
8#  SIMINT_MAXAM=5 ./build_simint.sh
9#
10if  [ -z "$(command -v python3)" ]; then
11    echo python3 not installed
12    echo please install python3
13    exit 1
14fi
15if  [ -z "$(command -v curl)" ] && [ -z "$(command -v wget)" ]; then
16    echo curl and wget not installed
17    echo please install curl or wget
18    exit 1
19fi
20if  [ -z "$(command -v patch)" ]; then
21    echo patch not installed
22    echo please install patch
23    exit 1
24fi
25UNAME_S=$(uname -s)
26if [[ ${UNAME_S} == Linux ]]; then
27    CPU_FLAGS=$(cat /proc/cpuinfo | grep flags |tail -n 1)
28    CPU_FLAGS_2=$(cat /proc/cpuinfo | grep flags |tail -n 1)
29elif [[ ${UNAME_S} == Darwin ]]; then
30    CPU_FLAGS=$(sysctl -n machdep.cpu.features)
31    CPU_FLAGS_2=$(sysctl -n machdep.cpu.leaf7_features)
32else
33    echo Operating system not supported yet
34    exit 1
35fi
36  GOTSSE2=$(echo ${CPU_FLAGS}   | tr  'A-Z' 'a-z'| awk ' /sse2/   {print "Y"}')
37   GOTAVX=$(echo ${CPU_FLAGS}   | tr  'A-Z' 'a-z'| awk ' /avx/    {print "Y"}')
38  GOTAVX2=$(echo ${CPU_FLAGS_2} | tr  'A-Z' 'a-z'| awk ' /avx2/   {print "Y"}')
39GOTAVX512=$(echo ${CPU_FLAGS}   | tr  'A-Z' 'a-z'| awk ' /avx512f/{print "Y"}')
40if [[ -n "${SIMINT_VECTOR}" ]]; then
41      VEC=${SIMINT_VECTOR}
42elif [[ "${GOTAVX512}" == "Y" ]]; then
43    VEC=avx512
44elif [[ "${GOTAVX2}" == "Y" ]]; then
45    VEC=avx2
46elif [[ "${GOTAVX}" == "Y" ]]; then
47    VEC=avx
48elif [[ "${GOTSSE2}" == "Y" ]]; then
49    VEC=sse
50else
51    VEC=scalar
52fi
53echo VEC $VEC
54if [[ "${VEC}" == "avx512" ]]; then
55if [[   -z "${CC}" ]]; then
56    CC=cc
57fi
58GCC_EXTRA=$(echo $CC | cut -c 1-3)
59if [ "$GCC_EXTRA" == gcc ]; then
60let GCCVERSIONGT5=$(expr `${CC} -dumpversion | cut -f1 -d.` \> 5)
61#echo exit code "$?"
62    if [[ ${GCCVERSIONGT5} != 1 ]]; then
63	echo
64	echo you have gcc version $(${CC} -dumpversion | cut -f1 -d.)
65	echo gcc version 6 and later needed for skylake
66	echo
67	exit 1
68    fi
69fi
70fi
71SRC_HOME=`pwd`
72DERIV=1
73if [[  -z "${SIMINT_MAXAM}" ]]; then
74    SIMINT_MAXAM=3
75fi
76#PERMUTE_SLOW=1
77PERMUTE_SLOW=${SIMINT_MAXAM}
78GITHUB_USERID=edoapra
79#rm -rf simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIVE}* *-chem-simint-generator-?????? simint-chem-simint-generator.tar.gz simint_lib
80rm -rf simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIVE}* *-chem-simint-generator-?????? simint_lib
81
82GITHUB_URL=https://github.com/${GITHUB_USERID}/simint-generator/tarball/master
83#GITHUB_URL=https://github.com/simint-chem/simint-generator/tarball/master
84TAR_NAME=simint-chem-simint-generator.tar.gz
85if [ -f  ${TAR_NAME} ]; then
86    echo "using existing"  ${TAR_NAME}
87else
88if  [ ! -z "$(command -v curl)" ] ; then
89    curl -L "${GITHUB_URL}" -o "${TAR_NAME}"
90else
91    wget -O "${TAR_NAME}" "${GITHUB_URL}"
92fi
93fi
94tar xzf simint-chem-simint-generator.tar.gz
95cd *-simint-generator-???????
96rm -f generator_types.patch
97cat > generator_types.patch <<EOF
98--- simint-chem-simint-generator-c589bd7/generator/CommandLine.hpp	2018-12-11 10:48:31.000000000 -0800
99+++ modif/generator/CommandLine.hpp	2019-09-17 09:25:45.000000000 -0700
100@@ -10,6 +10,7 @@
101 
102 #include <vector>
103 #include "generator/Options.hpp"
104+#include "generator/Types.hpp"
105 
106 
107 /*! \brief Get the next argument on the command line
108--- simint-chem-simint-generator-c589bd7/skel/simint/vectorization/intrinsics_avx512.h.org	2019-09-19 23:15:32.768327180 -0700
109+++ modif/skel/simint/vectorization/intrinsics_avx512.h	2019-09-19 23:15:49.232376802 -0700
110@@ -207,7 +207,7 @@
111         return u.v;
112     }
113     
114-    #define SIMINT_PRIM_SCREEN_STAT
115+    #define SIMINT_PRIM_SCREEN_STAT__
116     static inline
117     int count_prim_screen_survival(__m512d screen_val, const double screen_tol)
118     {
119edo@durian:~/nwchem/nwchem-master/src/NWints/simint/libsimint_source/edoapra-simint-generator-f690e3a$ diff -u skel/simint/vectorization/intrinsics_avx.h.org skel/simint/vectorization/intrinsics_avx.h 
120--- simint-chem-simint-generator-c589bd7/skel/simint/vectorization/intrinsics_avx.h.org	2019-09-19 23:16:00.400410460 -0700
121+++ modif/skel/simint/vectorization/intrinsics_avx.h	2019-09-19 23:16:11.060442586 -0700
122@@ -216,7 +216,7 @@
123         return u.v;
124     }
125     
126-    #define SIMINT_PRIM_SCREEN_STAT
127+    #define SIMINT_PRIM_SCREEN_STAT__
128     static inline
129     int count_prim_screen_survival(__m256d screen_val, const double screen_tol)
130     {
131EOF
132patch -p1 < ./generator_types.patch
133pwd
134mkdir -p build; cd build
135if [[ -z "${MYCMAKE}" ]]; then
136    #look for cmake
137    if [[ -z "$(command -v cmake)" ]]; then
138	echo cmake required to build Simint
139	echo Please install cmake
140	echo define the CMAKE env. variable
141	exit 1
142    else
143	MYCMAKE=cmake
144    fi
145fi
146CMAKE_VER=$(${MYCMAKE} --version|cut -d " " -f 3|head -1|cut -c1)
147#echo CMAKE_VER is ${CMAKE_VER}
148if [[ ${CMAKE_VER} -lt 3 ]]; then
149    echo CMake 3.0.2 or higher is required
150    echo Please install CMake 3
151    echo define the MYCMAKE env. variable
152    exit 1
153fi
154if [[ -z "${SIMINT_BUILD_TYPE}" ]]; then
155    SIMINT_BUILD_TYPE=Release
156fi
157$MYCMAKE  -DCMAKE_BUILD_TYPE="${SIMINT_BUILD_TYPE}"  ../
158make -j2
159cd ..
160#./create.py -g build/generator/ostei -l 6 -p 4 -d 1 simint.l6_p4_d1
161#create.py -g build/generator/ostei -l 4 -p 4 -d 0 -ve 4 -he 4 -vg 5 -hg 5
162#https://www.cc.gatech.edu/~echow/pubs/huang-chow-sc18.pdf
163#workaround for PYTHONHOME crazyness
164if [[ ! -z "${PYTHONHOME}" ]]; then
165    export PYTHONHOMESET=${PYTHONHOME}
166    unset PYTHONHOME
167    echo 'PYTHONOME unset'
168fi
169time -p ./create.py -g build/generator/ostei -l ${SIMINT_MAXAM} -p ${PERMUTE_SLOW} -d ${DERIV} ../simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIV}  -ve 4 -he 4 -vg 5 -hg 5
170if [[ ! -z "${PYTHONHOME}" ]]; then
171    export PYTHONHOME=${PYTHONHOMESET}
172    unset PYTHONHOMESET
173    echo 'PYTHONOME set'
174fi
175cd ../simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIV}
176mkdir -p build
177cd build
178if [[ -z "${CXX}" ]]; then
179    #look for c++
180    if  [ -z "$(command -v c++)" ]; then
181        echo c++ not installed
182        echo please install a C++ compiler and
183        echo define the CXX env. variable
184	exit 1
185    else
186	CXX=c++
187    fi
188fi
189if [[ -z "${FC}" ]]; then
190    #look for gfortran
191    if  [ -z "$(command -v gfortran)" ]; then
192        echo gfortran not installed
193        echo please install a Fortran compiler and
194        echo define the FC env. variable
195	exit 1
196    else
197	FC=gfortran
198    fi
199fi
200    GFORTRAN_EXTRA=$(echo $FC | cut -c 1-8)
201if [[ ${FC} == gfortran  || ${FC} == flang  ||  ${GFORTRAN_EXTRA} == gfortran || (${FC} == ftn && ${PE_ENV} == GNU) || (${FC} == ftn && ${PE_ENV} == AOCC) ]] ; then
202    Fortran_FLAGS="-fdefault-integer-8 -cpp"
203    GNUMAJOR=$(${FC} -dM -E - < /dev/null 2> /dev/null | grep __GNUC__ |cut -c18-)
204    echo GNUMAJOR is $GNUMAJOR
205    if [ $GNUMAJOR -ge 8 ]; then
206    Fortran_FLAGS+=" -std=legacy "
207    fi
208elif  [ ${FC} == xlf ] || [ ${FC} == xlf_r ] || [ ${FC} == xlf90 ]|| [ ${FC} == xlf90_r ]; then
209    Fortran_FLAGS=" -qintsize=8 -qextname -qpreprocess"
210elif  [[ ${FC} == ifort || (${FC} == ftn && ${PE_ENV} == INTEL) ]]; then
211    Fortran_FLAGS="-i8 -fpp"
212elif  [ ${FC} == ftn ]  && [ ${PE_ENV} == CRAY  ]; then
213    Fortran_FLAGS=" -ffree -s integer64 -e F "
214elif  [[ ${FC} == nvfortran || ${FC} == pgf90 || (${FC} == ftn && ${PE_ENV} == NVIDIA) ]]; then
215    Fortran_FLAGS="-i8 -cpp"
216    CC=gcc
217    CXX=g++
218    if  [[ ${PE_ENV} == NVIDIA ]]; then
219	unset CPATH
220    fi
221fi
222echo Fortran_FLAGS equal "$Fortran_FLAGS"
223FC="${FC}" CC="${CC}" CXX="${CXX}" $MYCMAKE \
224 -DCMAKE_BUILD_TYPE="${SIMINT_BUILD_TYPE}" -DSIMINT_VECTOR=${VEC}  \
225 -DCMAKE_INSTALL_LIBDIR=lib -DENABLE_FORTRAN=ON -DSIMINT_MAXAM=${SIMINT_MAXAM} -DSIMINT_MAXDER=${DERIV} \
226 -DENABLE_TESTS=OFF     -DSIMINT_STANDALONE=OFF   \
227 -DCMAKE_Fortran_FLAGS="$Fortran_FLAGS" -DCMAKE_INSTALL_PREFIX=${SRC_HOME}/simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIV}.install ../
228time -p make  -j2
229make simint
230if [[ (${FC} == ftn && ${PE_ENV} == CRAY) ]] ; then
231    cp simint/SIMINTFORTRAN.mod simint/simintfortran.mod
232fi
233make install/fast
234cd ../..
235echo ln -sf  simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIV}.install simint_install
236ln -sf  simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIV}.install simint_install
237cd simint_install/lib
238ln -sf libsimint.a libnwc_simint.a
239export SIMINT_HOME=${SRC_HOME}/simint.l${SIMINT_MAXAM}_p${PERMUTE_SLOW}_d${DERIV}.install
240echo 'SIMINT library built with maximum angular momentum='${SIMINT_MAXAM}
241echo SIMINT_HOME="$SIMINT_HOME"
242exit 0
243# remainder of script not used since flow goes back to makefile
244export USE_SIMINT=1
245make clean
246make V=1
247pwd
248cd ../api
249touch `egrep -l SIM *F`
250make V=1
251cd ../..
252make V=1  link
253echo 'NWChem built with SIMINT support. Maximum angular momentum='${SIMINT_MAXAM}
254echo SIMINT_HOME="$SIMINT_HOME"
255