Update linking to MKL and document same
authorMark Abraham <mark.j.abraham@gmail.com>
Mon, 11 Mar 2013 11:31:15 +0000 (12:31 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Fri, 26 Apr 2013 06:37:56 +0000 (16:37 +1000)
Works using nifty feature from icc 11 and up, or any other compiler if
the user does the legwork (which is all we ever used to offer).

Code that used HAVE_LIBMKL had a bug, which we never saw because
the top-level CMakeLists.txt set HAVE_MKL. Fixed that.

Removed unused TextMKL.c code - check_function_exists() is sufficient.

Refs #1110,#1186

Change-Id: I39a66673e5fe571a5f8b0691bbe2ec619cd60778

CMakeLists.txt
admin/installguide/installguide.tex
cmake/FindMKL.cmake [deleted file]
cmake/TestMKL.c [deleted file]
src/gmxlib/copyrite.c

index df12172a9a74370c7bfcaa51507c9db3d1b19a74..d78d99dde85a7dd256d4ce50970fb4b3fcb15393 100644 (file)
@@ -901,6 +901,11 @@ endif(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
 string(TOUPPER ${GMX_FFT_LIBRARY} GMX_FFT_LIBRARY)
 set(PKG_FFT "")
 set(PKG_FFT_LIBS "")
+set(MKL_LIBRARIES_FORMAT_DESCRIPTION "Use full paths to library files, in the right order, and separated by semicolons.")
+set(MKL_LIBRARIES "" CACHE STRING "List of libraries for linking to MKL. Only used with GMX_FFT_LIBRARY=mkl. ${MKL_LIBRARIES_FORMAT_DESCRIPTION}")
+set(MKL_INCLUDE_DIR "" CACHE PATH "Path to mkl.h (non-inclusive). Only used with GMX_FFT_LIBRARY=mkl.")
+mark_as_advanced(FORCE MKL_LIBRARIES)
+mark_as_advanced(FORCE MKL_INCLUDE_DIR)
 if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
     if(GMX_DOUBLE)
         set(FFTW fftw)
@@ -934,14 +939,58 @@ if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
     endif()
 
 elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
-#    MESSAGE(STATUS "Using external FFT library - Intel MKL")
-    find_package(MKL REQUIRED)
-    include_directories(${MKL_INCLUDE_DIR})
-    set(FFT_LIBRARIES ${MKL_LIBRARIES})
-    set(PKG_FFT_LIBS ${MKL_LIBRARIES})
+    MESSAGE(STATUS "Using external FFT library - Intel MKL")
+
+    # Intel 11 and up makes life somewhat easy if you just want to use
+    # all their stuff. It's not easy if you only want some of their
+    # stuff...
+    if (CMAKE_C_COMPILER_ID MATCHES "Intel" AND C_COMPILER_VERSION VERSION_GREATER "11")
+        # The next line takes care of everything for MKL
+        if (WIN32)
+            set(FFT_LINKER_FLAGS "/Qmkl=sequential")
+        else()
+            set(FFT_LINKER_FLAGS "-mkl=sequential")
+        endif()
+        set(MKL_ERROR_MESSAGE "Make sure you have configured your compiler so that ${FFT_LINKER_FLAGS} will work.")
+    else()
+        # The user will have to provide the set of magic libraries in
+        # MKL_LIBRARIES, which we cache (non-advanced), so that they
+        # don't have to keep specifying it, and can easily see that
+        # CMake is still using that information.
+        set(MKL_LIBRARIES "${MKL_LIBRARIES}" CACHE STRING "User-specified libraries for linking to MKL")
+        mark_as_advanced(CLEAR MKL_LIBRARIES)
+        include_directories(${MKL_INCLUDE_DIR})
+        mark_as_advanced(CLEAR MKL_INCLUDE_DIR)
+        set(FFT_LIBRARIES "${MKL_LIBRARIES}")
+        set(MKL_ERROR_MESSAGE "The include path to mkl.h in MKL_INCLUDE_DIR, and the link libraries in MKL_LIBRARIES=${MKL_LIBRARIES} need to match what the MKL documentation says you need for your system. ${MKL_LIBRARIES_FORMAT_DESCRIPTION}")
+        # Convert the semi-colon separated list to a list of
+        # command-line linker arguments so that code using our
+        # pkgconfig setup can use it.
+        string(REGEX REPLACE ";" " " PKG_FFT_LIBS "${MKL_LIBRARIES}")
+    endif()
+
+    # Check MKL works. If we were in a non-global scope, we wouldn't
+    # have to play nicely.
+    set(old_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+    set(CMAKE_REQUIRED_FLAGS "${FFT_LINKER_FLAGS}")
+    set(old_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+    set(CMAKE_REQUIRED_LIBRARIES "${FFT_LIBRARIES}")
+
+    check_function_exists(DftiCreateDescriptor TEST_MKL)
+
+    set(CMAKE_REQUIRED_FLAGS "${old_CMAKE_REQUIRED_FLAGS}")
+    set(CMAKE_REQUIRED_LIBRARIES "${old_CMAKE_REQUIRED_LIBRARIES}")
+
+    if(NOT TEST_MKL)
+        # Hack to help the user vary MKL settings until they work.
+        # TODO Make this logic more useful.
+        unset(TEST_MKL CACHE)
+        message(FATAL_ERROR "Linking with MKL was requested, but was not successful. ${MKL_ERROR_MESSAGE}")
+    endif()
 
+    # Set variables to signal that we have MKL available and should use it for FFTs.
     set(GMX_FFT_MKL 1)
-    set(HAVE_MKL 1)
+    set(HAVE_LIBMKL 1)
 
 #elseif(${GMX_FFT_LIBRARY} STREQUAL "ACML")
 #    MESSAGE(STATUS "Using external FFT library - AMD core math library")
@@ -961,7 +1010,7 @@ endif()
 set(GMX_EXTERNAL_BLAS TRUE CACHE BOOL "Use external BLAS instead of built-in")
 set(GMX_EXTERNAL_LAPACK TRUE CACHE BOOL "Use external LAPACK instead of built-in")
 # MKL has BLAS/LAPACK routines
-if(NOT HAVE_MKL AND NOT ACCELERATE_FRAMEWORK)
+if(NOT HAVE_LIBMKL AND NOT ACCELERATE_FRAMEWORK)
   if(GMX_EXTERNAL_BLAS)
     if (GMX_BLAS_USER)
         list(APPEND GMX_EXTRA_LIBRARIES ${GMX_BLAS_USER})
@@ -1056,7 +1105,7 @@ endif(GMX_FAHCORE)
 if (NOT GMX_SKIP_DEFAULT_CFLAGS)
     set(CMAKE_C_FLAGS "${ACCELERATION_C_FLAGS} ${MPI_COMPILE_FLAGS} ${CMAKE_C_FLAGS}")
     set(CMAKE_CXX_FLAGS "${ACCELERATION_CXX_FLAGS} ${MPI_COMPILE_FLAGS} ${CMAKE_CXX_FLAGS}")
-    set(CMAKE_EXE_LINKER_FLAGS "${MPI_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}")
+    set(CMAKE_EXE_LINKER_FLAGS "${FFT_LINKER_FLAGS} ${MPI_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}")
     set(CMAKE_SHARED_LINKER_FLAGS "${MPI_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}")
 else()
     message("Recommended flags which are not added because GMX_SKIP_DEFAULT_CFLAGS=yes:")
@@ -1068,7 +1117,7 @@ else()
         message("CMAKE_CXX_FLAGS_RELEASE: ${GMXC_CXXFLAGS_RELEASE}")
         message("CMAKE_CXX_FLAGS_DEBUG: ${GMXC_CXXFLAGS_DEBUG}")
     endif()
-    message("CMAKE_EXE_LINKER_FLAGS: ${MPI_LINKER_FLAGS}")
+    message("CMAKE_EXE_LINKER_FLAGS: ${FFT_LINKER_FLAGS} ${MPI_LINKER_FLAGS}")
     message("CMAKE_SHARED_LINKER_FLAGS: ${MPI_LINKER_FLAGS}")
 endif()
 
index cb7e272b998dc4fb7cfcb1c63c287361621503ce..a7783e53faa1074d28b8214b2d339a968784ea94 100644 (file)
@@ -255,11 +255,19 @@ support has been compiled into \fftw{}, so you need to set this at compile time.
 
 \subsubsection{\mkl{}}
 
-Using \mkl{} requires a set of linker flags that \gromacs{} is not
-able to detect for you, so setting up optimal linking is tricky at the
-moment. You will need to consult your compiler documentation and
-use \verb+CMAKE_C_FLAGS+ and \verb+-DCMAKE_EXE_LINKER_FLAGS+
-accordingly.
+Using \mkl{} with \icc{} 11 or higher is very simple. Set up your
+compiler environment correctly, perhaps with a command like
+\verb+source /path/to/compilervars.sh intel64+ (or consult your local
+documentation). Then set \verb+-DGMX_FFT_LIBRARY=mkl+ when you run
+\cmake{}. In this case, \gromacs{} will also use \mkl{} for \blas{}
+and \lapack{} (see \hyperref{linear-algebra}{here}).
+
+Otherwise, you can configure \mkl{} by setting
+\verb+-DGMX_FFT_LIBRARY=mkl
+-DMKL_LIBRARIES="/full/path/to/libone.so;/full/path/to/libtwo.so"
+-DMKL_INCLUDE_DIR="/full/path/to/mkl/include"+,
+where the full list (and order!) of libraries you require are found in
+Intel's \mkl{} documentation for your system.
 
 \subsection{Optional build components}
 
@@ -437,6 +445,9 @@ back on internal versions provided in the \gromacs{} source. These are
 fine for normal use. If you need to specify a non-standard path to
 search, use \verb+-DCMAKE_PREFIX_PATH=/path/to/search+.
 
+If you are using Intel's \mkl{} for \fft{}, then the \blas{} and
+\lapack{} it provides are used automatically.
+
 On Apple platforms where the Accelerate Framework is available, these
 will be automatically used for \blas{} and \lapack{}.
 
diff --git a/cmake/FindMKL.cmake b/cmake/FindMKL.cmake
deleted file mode 100644 (file)
index f240bbc..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# This file is part of the GROMACS molecular simulation package.
-#
-# Copyright (c) 2012,2013, by the GROMACS development team, led by
-# David van der Spoel, Berk Hess, Erik Lindahl, and including many
-# others, as listed in the AUTHORS file in the top-level source
-# directory and at http://www.gromacs.org.
-#
-# GROMACS is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation; either version 2.1
-# of the License, or (at your option) any later version.
-#
-# GROMACS is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with GROMACS; if not, see
-# http://www.gnu.org/licenses, or write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
-#
-# If you want to redistribute modifications to GROMACS, please
-# consider that scientific software is very special. Version
-# control is crucial - bugs must be traceable. We will be happy to
-# consider code for inclusion in the official distribution, but
-# derived work must not be called official GROMACS. Details are found
-# in the README & COPYING files - if they are missing, get the
-# official version at http://www.gromacs.org.
-#
-# To help us fund GROMACS development, we humbly ask that you cite
-# the research papers on the package. Check out http://www.gromacs.org.
-#
-# - Find Intel MKL
-# Find the Intel Math Kernel Library, version 6.0 or later
-#
-#  MKL_INCLUDE_DIR - where to find mkl_dfti.h
-#  MKL_LIBRARIES   - List of libraries when using MKL
-#  MKL_FOUND       - True if MKL was found
-
-if (MKL_INCLUDE_DIR)
-  # Already in cache, be silent
-  set (MKL_FIND_QUIETLY TRUE)
-endif (MKL_INCLUDE_DIR)
-
-find_path (MKL_INCLUDE_DIR mkl_dfti.h)
-find_library (MKL_LIBRARIES mkl_core)
-
-# handle the QUIETLY and REQUIRED arguments and set MKL_FOUND to TRUE if
-# all listed variables are TRUE
-include (FindPackageHandleStandardArgs)
-find_package_handle_standard_args (MKL DEFAULT_MSG MKL_LIBRARIES MKL_INCLUDE_DIR)
-
-# MKL Libraries change name ALL the time, so the user will have to set these...
-# mark_as_advanced (MKL_LIBRARIES MKL_INCLUDE_DIR)
-
-
diff --git a/cmake/TestMKL.c b/cmake/TestMKL.c
deleted file mode 100644 (file)
index 0998363..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <mkl_dfti.h>
-
-int
-main()
-{
-  DFTI_DESCRIPTOR *desc;
-  MKL_LONG nx = 10;
-
-  DftiCreateDescriptor(&desc,DFTI_SINGLE,DFTI_COMPLEX,1,nx);
-}
index ae32be48e89de743c9856b2f2b65f32fe07474bf..812ff314e4b96c1fd48a036fa2ea99610c1199c0 100644 (file)
@@ -758,7 +758,7 @@ void gmx_print_version_info(FILE *fp)
     }
 #ifdef HAVE_LIBMKL
     /* MKL might be used for LAPACK/BLAS even if FFTs use FFTW, so keep it separate */
-    fprintf(fp, "Linked with Intel MKL version %s.%s.%s.\n",
+    fprintf(fp, "Linked with Intel MKL version %d.%d.%d.\n",
             __INTEL_MKL__, __INTEL_MKL_MINOR__, __INTEL_MKL_UPDATE__);
 #endif
 #ifdef GMX_GPU