From 111bb5152b62a4f4bb4f7ea0f1ec22d4ff5859a0 Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Tue, 5 May 2015 20:14:10 +0200
Subject: [PATCH] Allow external blas with internal lapack

Notice that on machines where internal lapack were used
./configure should be run again.
---
 .travis.yml          |  3 +-
 configure            | 72 ++++++++++++++++++++++++++++++++++++--------
 configure.ac         | 45 +++++++++++++++++++++------
 src/blas/blas.cpp    |  2 +-
 src/blas/blas.h      |  8 +++--
 src/blas/import.sh   | 12 +++++---
 src/lapack/import.sh |  2 +-
 7 files changed, 113 insertions(+), 31 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index fa2a9e022..dce49cf95 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,8 @@ env:
 # then check with different optimization flags
   - PLUMED_CC=clang PLUMED_CXX=clang++ PLUMED_CXXFLAGS=-O3 LAPACK=yes
   - PLUMED_CC=gcc   PLUMED_CXX=g++     PLUMED_CXXFLAGS=-O3 LAPACK=yes
-  - PLUMED_CC=mpicc PLUMED_CXX=mpic++  PLUMED_CXXFLAGS=-O3 LAPACK=yes
+# test using external blas with internal lapack
+  - PLUMED_CC=mpicc PLUMED_CXX=mpic++  PLUMED_CXXFLAGS=-O3 LAPACK=yes CONFIG_FLAGS="--disable-external-lapack"
 # cppcheck
 # in principle we should make only "cppcheck" here
   - PLUMED_CC=gcc   PLUMED_CXX=g++   CPPCHECK=yes
diff --git a/configure b/configure
index ea9d71c5b..e504fd1c1 100755
--- a/configure
+++ b/configure
@@ -695,6 +695,7 @@ enable_cxx_exceptions
 enable_mpi
 enable_openmp
 enable_external_lapack
+enable_external_blas
 enable_molfile_plugins
 enable_external_molfile_plugins
 enable_matheval
@@ -1345,6 +1346,7 @@ Optional Features:
   --enable-openmp         enable search for openmp, default: no
   --enable-external-lapack
                           enable search for external lapack, default: yes
+  --enable-external-blas  enable search for external blas, default: yes
   --enable-molfile-plugins
                           enable use molfile_plugins, default: yes
   --enable-external-molfile-plugins
@@ -2428,6 +2430,24 @@ fi
 
 
 
+external_blas=
+# Check whether --enable-external-blas was given.
+if test "${enable_external_blas+set}" = set; then :
+  enableval=$enable_external_blas; case "${enableval}" in
+             (yes) external_blas=true ;;
+             (no)  external_blas=false ;;
+             (*)   as_fn_error $? "wrong argument to --enable-external-blas" "$LINENO" 5 ;;
+  esac
+else
+  case "yes" in
+             (yes) external_blas=true ;;
+             (no)  external_blas=false ;;
+  esac
+
+fi
+
+
+
 molfile_plugins=
 # Check whether --enable-molfile-plugins was given.
 if test "${enable_molfile_plugins+set}" = set; then :
@@ -5110,8 +5130,18 @@ save_LIBS="$LIBS"
 blas_found=
 lapack_found=
 
-if test "$external_lapack" == true ; then
+# if external lapack can only work with external blas
+# thus, if external blas are disabled also external lapack should be disabled
+if test "$external_blas" == false && test "$external_lapack" == true ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: Internal blas can only be used with internal lapack" >&5
+$as_echo "$as_me: Internal blas can only be used with internal lapack" >&6;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: Will not search for external lapack" >&5
+$as_echo "$as_me: Will not search for external lapack" >&6;}
+  external_lapack=false
+fi
 
+# first look for blas
+if test "$external_blas" == true ; then
 ac_fn_cxx_check_func "$LINENO" "dgemv" "ac_cv_func_dgemv"
 if test "x$ac_cv_func_dgemv" = xyes; then :
   blas_found=nounderscore
@@ -5209,8 +5239,26 @@ fi
 
 fi
 
+fi
+
+# if not found, then use internal lapack and blas
+if test -z "$blas_found" ; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using internal lapack and blas, could be inefficient" >&5
+$as_echo "$as_me: WARNING: using internal lapack and blas, could be inefficient" >&2;}
+LIBS="$save_LIBS"
+
+$as_echo "#define __PLUMED_INTERNAL_BLAS 1" >>confdefs.h
+
+$as_echo "#define __PLUMED_INTERNAL_LAPACK 1" >>confdefs.h
+
+fi
 
+# if found, also look for external blas
 if test -n "$blas_found" ; then
+
+save_LIBS="$LIBS"
+
+if test "$external_lapack" == true ; then
 # Then we look for lapack using same underscoring
 case "$blas_found" in
 (underscore) search_for=dsyevr_ ;;
@@ -5270,25 +5318,25 @@ fi
 
 fi
 
-fi
-
+# if not found, then use internal lapack with external blas
 if test -z "$lapack_found" ; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using internal lapack/blas, could be inefficient" >&5
-$as_echo "$as_me: WARNING: using internal lapack/blas, could be inefficient" >&2;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using internal lapack, could be inefficient" >&5
+$as_echo "$as_me: WARNING: using internal lapack, could be inefficient" >&2;}
 LIBS="$save_LIBS"
 
 $as_echo "#define __PLUMED_INTERNAL_LAPACK 1" >>confdefs.h
 
-$as_echo "#define __PLUMED_INTERNAL_BLAS 1" >>confdefs.h
-
+fi
 
-else
+fi
 
-  if test $blas_found == nounderscore
-  then
-    $as_echo "#define F77_NO_UNDERSCORE 1" >>confdefs.h
+# in case external blas have been found, take note of their underscoring
+# notice that this applies also when external blas are used with internal lapack
+# in the latter case, also (internal) lapack names will be underscored consistently
+if test "$blas_found" == nounderscore
+then
+  $as_echo "#define F77_NO_UNDERSCORE 1" >>confdefs.h
 
-  fi
 fi
 
 #### End of compulsory libraries ####
diff --git a/configure.ac b/configure.ac
index 46363169e..5feac2ccd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -92,6 +92,7 @@ PLUMED_CONFIG_ENABLE([cxx_exceptions],[cxx-exceptions],[c++ exceptions],[no])
 PLUMED_CONFIG_ENABLE([mpi],[mpi],[search for mpi],[yes])
 PLUMED_CONFIG_ENABLE([openmp],[openmp],[search for openmp],[no])
 PLUMED_CONFIG_ENABLE([external_lapack],[external-lapack],[search for external lapack],[yes])
+PLUMED_CONFIG_ENABLE([external_blas],[external-blas],[search for external blas],[yes])
 PLUMED_CONFIG_ENABLE([molfile_plugins],[molfile-plugins],[use molfile_plugins],[yes])
 PLUMED_CONFIG_ENABLE([external_molfile_plugins],[external-molfile-plugins],[search for external molfile_plugins],[yes])
 PLUMED_CONFIG_ENABLE([matheval],[matheval],[search for matheval],[yes])
@@ -203,15 +204,38 @@ save_LIBS="$LIBS"
 blas_found=
 lapack_found=
 
-if test "$external_lapack" == true ; then
+# if external lapack can only work with external blas
+# thus, if external blas are disabled also external lapack should be disabled
+if test "$external_blas" == false && test "$external_lapack" == true ; then
+  AC_MSG_NOTICE([Internal blas can only be used with internal lapack])
+  AC_MSG_NOTICE([Will not search for external lapack])
+  external_lapack=false
+fi
 
+# first look for blas
+if test "$external_blas" == true ; then
 AC_CHECK_FUNC(  [dgemv], [blas_found=nounderscore], [
 AC_CHECK_FUNC(  [dgemv_],[blas_found=underscore],   [
 AC_CHECK_LIB(   [blas],[dgemv],  [LIBS="-lblas $LIBS"] [blas_found=nounderscore], [
 AC_CHECK_LIB(   [blas],[dgemv_], [LIBS="-lblas $LIBS"] [blas_found=underscore]
 ) ]) ]) ])
+fi
 
+# if not found, then use internal lapack and blas
+if test -z "$blas_found" ; then
+AC_MSG_WARN([using internal lapack and blas, could be inefficient])
+LIBS="$save_LIBS"
+
+AC_DEFINE([__PLUMED_INTERNAL_BLAS])
+AC_DEFINE([__PLUMED_INTERNAL_LAPACK])
+fi
+
+# if found, also look for external blas
 if test -n "$blas_found" ; then
+
+save_LIBS="$LIBS"
+
+if test "$external_lapack" == true ; then
 # Then we look for lapack using same underscoring
 case "$blas_found" in
 (underscore) search_for=dsyevr_ ;;
@@ -223,21 +247,22 @@ AC_CHECK_LIB(  [lapack],[$search_for], [LIBS="-llapack $LIBS"] [lapack_found=yes
 ])
 fi
 
-fi 
-
+# if not found, then use internal lapack with external blas
 if test -z "$lapack_found" ; then
-AC_MSG_WARN([using internal lapack/blas, could be inefficient])
+AC_MSG_WARN([using internal lapack, could be inefficient])
 LIBS="$save_LIBS"
 
 AC_DEFINE([__PLUMED_INTERNAL_LAPACK])
-AC_DEFINE([__PLUMED_INTERNAL_BLAS])
+fi
 
-else
+fi 
 
-  if test $blas_found == nounderscore
-  then
-    AC_DEFINE([F77_NO_UNDERSCORE])
-  fi
+# in case external blas have been found, take note of their underscoring
+# notice that this applies also when external blas are used with internal lapack
+# in the latter case, also (internal) lapack names will be underscored consistently
+if test "$blas_found" == nounderscore
+then
+  AC_DEFINE([F77_NO_UNDERSCORE])
 fi
 
 #### End of compulsory libraries ####
diff --git a/src/blas/blas.cpp b/src/blas/blas.cpp
index 5c7a968a3..75b2a4621 100644
--- a/src/blas/blas.cpp
+++ b/src/blas/blas.cpp
@@ -20,7 +20,7 @@ better idea to use the full reference implementation.
 
 Erik Lindahl, 2008-10-07.
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-#if defined(__PLUMED_INTERNAL_LAPACK) || defined (__PLUMED_INTERNAL_BLAS)
+#if defined (__PLUMED_INTERNAL_BLAS)
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
diff --git a/src/blas/blas.h b/src/blas/blas.h
index 3de76bdb1..6c751f7af 100644
--- a/src/blas/blas.h
+++ b/src/blas/blas.h
@@ -92,11 +92,15 @@ Erik Lindahl, 2008-10-07.
  */
 
 #include "simple.h"
-#if defined(__PLUMED_INTERNAL_LAPACK) || defined (__PLUMED_INTERNAL_BLAS)
+#if defined (__PLUMED_INTERNAL_BLAS)
 #include "def_internal.h"
 namespace PLMD{
 namespace blas{
 #else
+namespace PLMD{
+namespace blas{
+}
+}
 #include "def_external.h"
 extern "C"{
 #endif
@@ -240,7 +244,7 @@ int
 
 
 }
-#if defined(__PLUMED_INTERNAL_LAPACK) || defined (__PLUMED_INTERNAL_BLAS)
+#if defined (__PLUMED_INTERNAL_BLAS)
 }
 #endif
 
diff --git a/src/blas/import.sh b/src/blas/import.sh
index 1a3decd0f..b292479e7 100755
--- a/src/blas/import.sh
+++ b/src/blas/import.sh
@@ -16,18 +16,22 @@ sed 's|"types/simple.h"|"simple.h"|' "$GRO"/include/gmx_blas.h |
            a++;
            if(a==1){
              print "#include \"simple.h\""
-             print "#if defined(__PLUMED_INTERNAL_LAPACK) || defined (__PLUMED_INTERNAL_BLAS)"
+             print "#if defined (__PLUMED_INTERNAL_BLAS)"
              print "#include \"def_internal.h\""
              print "namespace PLMD{"
              print "namespace blas{"
              print "#else"
+             print "namespace PLMD{"
+             print "namespace blas{"
+             print "}"
+             print "}"
              print "#include \"def_external.h\""
              print "extern \"C\"{"
              print "#endif"
            }
            if(a==2){
              print "}"
-             print "#if defined(__PLUMED_INTERNAL_LAPACK) || defined (__PLUMED_INTERNAL_BLAS)"
+             print "#if defined (__PLUMED_INTERNAL_BLAS)"
              print "}"
              print "#endif"
            }
@@ -74,7 +78,7 @@ cat << EOF > simple.h
 EOF
 
 {
-echo "#if defined(__PLUMED_INTERNAL_LAPACK) || defined (__PLUMED_INTERNAL_BLAS)"
+echo "#if defined (__PLUMED_INTERNAL_BLAS)"
 for file in "$GRO"/src/gmxlib/gmx_blas/*.c
 do
   awk '{
@@ -99,6 +103,6 @@ echo "#endif"
 } > blas.cpp
 
 cd ../
-./header.sh
+./header.sh blas
 
 
diff --git a/src/lapack/import.sh b/src/lapack/import.sh
index a8f97d8fd..e671b4021 100755
--- a/src/lapack/import.sh
+++ b/src/lapack/import.sh
@@ -107,6 +107,6 @@ echo "#endif"
 } | sed 's/static //' > lapack.cpp
 
 cd ../
-./header.sh
+./header.sh lapack
 
 
-- 
GitLab