Split up compare.*
[gromacs.git] / cmake / gmxManageLinearAlgebraLibraries.cmake
blob8c8562b9c75dc100154a1679ee369d26dc821284
2 # This file is part of the GROMACS molecular simulation package.
4 # Copyright (c) 2013,2014, by the GROMACS development team, led by
5 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 # and including many others, as listed in the AUTHORS file in the
7 # top-level source directory and at http://www.gromacs.org.
9 # GROMACS is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public License
11 # as published by the Free Software Foundation; either version 2.1
12 # of the License, or (at your option) any later version.
14 # GROMACS is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 # Lesser General Public License for more details.
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with GROMACS; if not, see
21 # http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24 # If you want to redistribute modifications to GROMACS, please
25 # consider that scientific software is very special. Version
26 # control is crucial - bugs must be traceable. We will be happy to
27 # consider code for inclusion in the official distribution, but
28 # derived work must not be called official GROMACS. Details are found
29 # in the README & COPYING files - if they are missing, get the
30 # official version at http://www.gromacs.org.
32 # To help us fund GROMACS development, we humbly ask that you cite
33 # the research papers on the package. Check out http://www.gromacs.org.
35 # Helper macro for the function below. We treat BLAS and LAPACK the same
36 # way, so there's no reason to duplicate the logic for them
38 # MESSSAGE_TEXT variable is accumulated while checks for these
39 # libraries fail, but the message is only emitted if we are forced to
40 # fall back on the internal version.
42 # Arguments should be:
43 #     name                 "BLAS" or "LAPACK"
44 #     function_in_library  the name of a function to use in a linking test of that library
45 macro(manage_linear_algebra_library name function_in_library)
46     set(_library_was_found 0)
48     # We could consider printing status messages at the beginning and
49     # end, which would require caching whether the previous provider
50     # was user/MKL/external/internal. It's possible (we do it for
51     # FFT), but the number of times the user changes these is pretty
52     # low, so let's solve that one in master branch when we have
53     # better CMake gear to support it.
54     if(GMX_EXTERNAL_${name} OR NOT DEFINED GMX_EXTERNAL_${name})
55         set(_find_quietly FALSE)
56         gmx_check_if_changed(_user_var_changed GMX_${name}_USER)
57         if (NOT DEFINED GMX_EXTERNAL_${name})
58             set(_user_var_changed TRUE)
59         endif()
60         if(DEFINED GMX_EXTERNAL_${name} AND NOT _user_var_changed)
61             set(_find_quietly TRUE)
62         endif()
63         set(_message_text)
64         # Check for user-specified libraries if external libraries have
65         # been specified (which is the default).
66         if(GMX_${name}_USER)
67             set(_libraries_to_link ${GMX_${name}_USER})
68             set(_library_was_found 1)
70             if(NOT _find_quietly)
71                 set(CMAKE_REQUIRED_LIBRARIES ${GMX_${name}_USER})
72                 if(_user_var_changed)
73                     unset(_${name}_user_works CACHE)
74                 endif()
75                 message(STATUS "Checking that user ${name} library ${GMX_${name}_USER} works")
76                 check_function_exists(${function_in_library} _${name}_user_works)
77                 if(NOT _${name}_user_works)
78                     message(WARNING "GMX_${name}_USER library ${GMX_${name}_USER} was specified, but it may not provide ${name}. We are proceeding by assuming you know what you are doing and that linking F77-style to this library will work.")
79                 endif()
81                 if(HAVE_LIBMKL)
82                     message(STATUS "MKL and GMX_${name}_USER were both specified. Using the latter for ${name}.")
83                 endif()
84             endif()
85         endif()
87         if(NOT _library_was_found AND HAVE_LIBMKL)
88             set(CMAKE_REQUIRED_LIBRARIES "${FFT_LIBRARIES}")
89             set(CMAKE_REQUIRED_FLAGS "${FFT_LINKER_FLAGS}")
90             # This may also not work correctly if the user changes
91             # MKL_LIBRARIES after the first run. However,
92             # MKL_LIBRARIES is only needed for icc version < 11, or
93             # for trying to use MKL with a non-Intel compiler, and we
94             # can live with that for now.
95             check_function_exists(${function_in_library} _${name}_mkl_works)
96             if(_${name}_mkl_works)
97                 # If we ever need to compile with MKL linear algebra and
98                 # not with FFT supplied by MKL, uncomment the next line
99                 # (and probably tweak other things).
100 #                list(APPEND LINEAR_ALGEBRA_LIBRARIES ${FFT_LINKER_FLAGS} ${FFT_LIBRARIES})
101                 set(_library_was_found 1)
102             else()
103                 set(_message_text "Intel's MKL was specified, and it should provide ${name}, but it does not. ")
104             endif()
105         endif()
107         # If detection of ${name} has never run, or none of the preceding
108         # detection succeeded, try to detect ${name} in the CMake
109         # detection paths, etc.
110         if (NOT _library_was_found)
111             set(${name}_FIND_QUIETLY ${_find_quietly})
112             # Note that this finds all kinds of system libraries,
113             # including Apple's Accelerate Framework (and perhaps MKL for
114             # icc < 11).
115             find_package(${name})
116             if (${name}_FOUND)
117                 set(_libraries_to_link ${${name}_LIBRARIES})
118                 set(_library_was_found 1)
119             endif()
120         endif()
122         if (NOT _library_was_found AND NOT _find_quietly)
123             message(STATUS "${_message_text}Using GROMACS built-in ${name}.")
124         endif()
125     endif()
127     # Default behaviour is to try to use an external library, but fall
128     # back on the internal one if none is found.
129     set(GMX_EXTERNAL_${name} ${_library_was_found} CACHE BOOL "Use a ${name} library that is external to GROMACS if possible (ON), or the internal GROMACS one (OFF)")
130     mark_as_advanced(GMX_EXTERNAL_${name})
131     # Default behaviour is to use a library found on the system or in
132     # GROMACS. The user must actively set GMX_${name}_USER if they
133     # want to specify a library.
134     gmx_dependent_cache_variable(
135         GMX_${name}_USER
136         "Use a ${name} library found on the system (OFF), or a ${name} library supplied by the user (any other value, which is a full path to that ${name} library)"
137         FILEPATH "" GMX_EXTERNAL_${name})
138     mark_as_advanced(GMX_${name}_USER)
140     if(GMX_EXTERNAL_${name})
141         if (NOT _library_was_found)
142             message(FATAL_ERROR "You have set GMX_EXTERNAL_${name}=ON to instruct GROMACS to use an external ${name} library, but no external library could be detected.")
143         endif()
144         # Actually trigger linking.
145         list(APPEND LINEAR_ALGEBRA_LIBRARIES ${_libraries_to_link})
146     else()
147         # Triggering the compilation of the internal version of the library is handled elsewhere.
148     endif()
149 endmacro()
151 # The default behaviour is to try to detect an "external" BLAS and/or
152 # LAPACK, perhaps provided by a vendor, use those if found, and
153 # otherwise fall back on the GROMACS internal implementations of
154 # these. If the libraries are not in a standard location, the user can
155 # indicate a search path with CMAKE_PREFIX_PATH.
157 # However, if we are using icc+mkl (so a build command that includes
158 # -mkl), then it is probably painful to try to link some other BLAS or
159 # LAPACK. In that case, we use the BLAS & LAPACK provided by MKL. In
160 # principle, we could offer a more configurable behaviour if/when
161 # there is need to (say) use vendor BLAS with MKL for FFTs.
163 # If the vendor BLAS and/or LAPACK have abnormal library names, then
164 # the default searching procedure will fail (e.g. Redmine #771). The
165 # GMX_(BLAS|LAPACK)_USER variables can be used to indicate the correct
166 # libraries. If these do not work, a warning is emitted and we try to
167 # use them anyway, assuming the user knows what they are doing.
169 # Inputs:
170 #     GMX_EXTERNAL_BLAS     user input about whether to detect BLAS
171 #     GMX_EXTERNAL_LAPACK   user input about whether to detect LAPACK
172 #     HAVE_LIBMKL           true if the build will link to MKL
173 #     FFT_LINKER_FLAGS      used iff HAVE_MKL
174 #     FFT_LIBRARIES         used iff HAVE_MKL
175 #     GMX_BLAS_USER         user input for BLAS libraries to use
176 #     GMX_LAPACK_USER       user input for LAPACK libraries to use
178 # This function sets the following cache variables:
179 #     GMX_EXTERNAL_BLAS     according to whether external BLAS is being used
180 #     GMX_EXTERNAL_LAPACK   according to whether external LAPACK is being used
181 #     GMX_BLAS_USER         off = use a system library;
182 #                           any other value = full path to the library to use
183 #     GMX_LAPACK_USER       off = use a system library;
184 #                           any other value = full path to the library to use
186 # This function sets the following variables in its parent scope:
187 #     LINEAR_ALGEBRA_LIBRARIES  will be set as required to add libraries required for linear algebra
189 function(gmxManageLinearAlgebraLibraries)
190     include(CheckFunctionExists)
191     # Probably not necessary to unset, but let's be clear about usage.
192     unset(LINEAR_ALGEBRA_LIBRARIES)
194     manage_linear_algebra_library(BLAS dgemm_)
195     set(BLAS_FIND_QUIETLY ON)
196     manage_linear_algebra_library(LAPACK cheev_)
198     # Propagate the new local value to the parent scope
199     set(LINEAR_ALGEBRA_LIBRARIES "${LINEAR_ALGEBRA_LIBRARIES}" PARENT_SCOPE)
200 endfunction()
202 gmxManageLinearAlgebraLibraries()