# # This is a CMake makefile. You can find the cmake utility and # information about it at http://www.cmake.org # # # This cmake file tries to find installed BLAS and LAPACK libraries. # It looks for an installed copy of the Intel MKL library first and then # attempts to find some other BLAS and LAPACK libraries if you don't have # the Intel MKL. # # blas_found - True if BLAS is available # lapack_found - True if LAPACK is available # found_intel_mkl - True if the Intel MKL library is available # found_intel_mkl_headers - True if Intel MKL headers are available # blas_libraries - link against these to use BLAS library # lapack_libraries - link against these to use LAPACK library # mkl_libraries - link against these to use the MKL library # mkl_include_dir - add to the include path to use the MKL library # openmp_libraries - Set to Intel's OpenMP library if and only if we # find the MKL. # setting this makes CMake allow normal looking if else statements SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) SET(blas_found 0) SET(lapack_found 0) SET(found_intel_mkl 0) SET(found_intel_mkl_headers 0) SET(lapack_with_underscore 0) SET(lapack_without_underscore 0) message(STATUS "Searching for BLAS and LAPACK") INCLUDE(CheckFunctionExists) if (UNIX OR MINGW) message(STATUS "Searching for BLAS and LAPACK") if (BUILDING_MATLAB_MEX_FILE) # # This commented out stuff would link directly to MATLAB's built in # BLAS and LAPACK. But it's better to not link to anything and do a #find_library(MATLAB_BLAS_LIBRARY mwblas PATHS ${MATLAB_LIB_FOLDERS} ) #find_library(MATLAB_LAPACK_LIBRARY mwlapack PATHS ${MATLAB_LIB_FOLDERS} ) #if (MATLAB_BLAS_LIBRARY AND MATLAB_LAPACK_LIBRARY) # add_subdirectory(external/cblas) # set(blas_libraries ${MATLAB_BLAS_LIBRARY} cblas ) # set(lapack_libraries ${MATLAB_LAPACK_LIBRARY} ) # set(blas_found 1) # set(lapack_found 1) # message(STATUS "Found MATLAB's BLAS and LAPACK libraries") #endif() # We need cblas since MATLAB doesn't provide cblas symbols. add_subdirectory(external/cblas) set(blas_libraries cblas ) set(blas_found 1) set(lapack_found 1) message(STATUS "Will link with MATLAB's BLAS and LAPACK at runtime (hopefully!)") ## Don't try to link to anything other than MATLAB's own internal blas ## and lapack libraries because doing so generally upsets MATLAB. So ## we just end here no matter what. return() endif() # First, search for libraries via pkg-config, which is the cleanest path find_package(PkgConfig) pkg_check_modules(BLAS_REFERENCE cblas) pkg_check_modules(LAPACK_REFERENCE lapack) # Make sure the cblas found by pkgconfig actually has cblas symbols. SET(CMAKE_REQUIRED_LIBRARIES "${BLAS_REFERENCE_LDFLAGS}") CHECK_FUNCTION_EXISTS(cblas_ddot PKGCFG_HAVE_CBLAS) if (BLAS_REFERENCE_FOUND AND LAPACK_REFERENCE_FOUND AND PKGCFG_HAVE_CBLAS) set(blas_libraries "${BLAS_REFERENCE_LDFLAGS}") set(lapack_libraries "${LAPACK_REFERENCE_LDFLAGS}") set(blas_found 1) set(lapack_found 1) set(REQUIRES_LIBS "${REQUIRES_LIBS} cblas lapack") message(STATUS "Found BLAS and LAPACK via pkg-config") return() endif() include(CheckTypeSize) check_type_size( "void*" SIZE_OF_VOID_PTR) if (SIZE_OF_VOID_PTR EQUAL 8) set( mkl_search_path /opt/intel/oneapi/mkl/latest/lib/intel64 /opt/intel/mkl/*/lib/em64t /opt/intel/mkl/lib/intel64 /opt/intel/lib/intel64 /opt/intel/mkl/lib /opt/intel/tbb/*/lib/em64t/gcc4.7 /opt/intel/tbb/lib/intel64/gcc4.7 /opt/intel/tbb/lib/gcc4.7 ) find_library(mkl_intel mkl_intel_lp64 ${mkl_search_path}) mark_as_advanced(mkl_intel) else() set( mkl_search_path /opt/intel/oneapi/mkl/latest/lib/ia32 /opt/intel/mkl/*/lib/32 /opt/intel/mkl/lib/ia32 /opt/intel/lib/ia32 /opt/intel/tbb/*/lib/32/gcc4.7 /opt/intel/tbb/lib/ia32/gcc4.7 ) find_library(mkl_intel mkl_intel ${mkl_search_path}) mark_as_advanced(mkl_intel) endif() include(CheckLibraryExists) # Get mkl_include_dir set(mkl_include_search_path /opt/intel/oneapi/mkl/latest/include /opt/intel/mkl/include /opt/intel/include ) find_path(mkl_include_dir mkl_version.h ${mkl_include_search_path}) mark_as_advanced(mkl_include_dir) if(NOT DLIB_USE_MKL_SEQUENTIAL AND NOT DLIB_USE_MKL_WITH_TBB) # Search for the needed libraries from the MKL. We will try to link against the mkl_rt # file first since this way avoids linking bugs in some cases. find_library(mkl_rt mkl_rt ${mkl_search_path}) find_library(openmp_libraries iomp5 ${mkl_search_path}) mark_as_advanced(mkl_rt openmp_libraries) # if we found the MKL if (mkl_rt) set(mkl_libraries ${mkl_rt} ) set(blas_libraries ${mkl_rt} ) set(lapack_libraries ${mkl_rt} ) set(blas_found 1) set(lapack_found 1) set(found_intel_mkl 1) message(STATUS "Found Intel MKL BLAS/LAPACK library") endif() endif() if (NOT found_intel_mkl) # Search for the needed libraries from the MKL. This time try looking for a different # set of MKL files and try to link against those. find_library(mkl_core mkl_core ${mkl_search_path}) set(mkl_libs ${mkl_intel} ${mkl_core}) mark_as_advanced(mkl_libs mkl_intel mkl_core) if (DLIB_USE_MKL_WITH_TBB) find_library(mkl_tbb_thread mkl_tbb_thread ${mkl_search_path}) find_library(mkl_tbb tbb ${mkl_search_path}) mark_as_advanced(mkl_tbb_thread mkl_tbb) list(APPEND mkl_libs ${mkl_tbb_thread} ${mkl_tbb}) elseif (DLIB_USE_MKL_SEQUENTIAL) find_library(mkl_sequential mkl_sequential ${mkl_search_path}) mark_as_advanced(mkl_sequential) list(APPEND mkl_libs ${mkl_sequential}) else() find_library(mkl_thread mkl_intel_thread ${mkl_search_path}) find_library(mkl_iomp iomp5 ${mkl_search_path}) find_library(mkl_pthread pthread ${mkl_search_path}) mark_as_advanced(mkl_thread mkl_iomp mkl_pthread) list(APPEND mkl_libs ${mkl_thread} ${mkl_iomp} ${mkl_pthread}) endif() # If we found the MKL if (mkl_intel AND mkl_core AND ((mkl_tbb_thread AND mkl_tbb) OR (mkl_thread AND mkl_iomp AND mkl_pthread) OR mkl_sequential)) set(mkl_libraries ${mkl_libs}) set(blas_libraries ${mkl_libs}) set(lapack_libraries ${mkl_libs}) set(blas_found 1) set(lapack_found 1) set(found_intel_mkl 1) message(STATUS "Found Intel MKL BLAS/LAPACK library") endif() endif() if (found_intel_mkl AND mkl_include_dir) set(found_intel_mkl_headers 1) endif() # try to find some other LAPACK libraries if we didn't find the MKL set(extra_paths /usr/lib64 /usr/lib64/atlas-sse3 /usr/lib64/atlas-sse2 /usr/lib64/atlas /usr/lib /usr/lib/atlas-sse3 /usr/lib/atlas-sse2 /usr/lib/atlas /usr/lib/openblas-base /opt/OpenBLAS/lib $ENV{OPENBLAS_HOME}/lib ) if (NOT blas_found) find_library(cblas_lib NAMES openblasp openblas PATHS ${extra_paths}) if (cblas_lib) set(blas_libraries ${cblas_lib}) set(blas_found 1) message(STATUS "Found OpenBLAS library") set(CMAKE_REQUIRED_LIBRARIES ${blas_libraries}) # If you compiled OpenBLAS with LAPACK in it then it should have the # sgetrf_single function in it. So if we find that function in # OpenBLAS then just use OpenBLAS's LAPACK. CHECK_FUNCTION_EXISTS(sgetrf_single OPENBLAS_HAS_LAPACK) if (OPENBLAS_HAS_LAPACK) message(STATUS "Using OpenBLAS's built in LAPACK") # set(lapack_libraries gfortran) set(lapack_found 1) endif() endif() mark_as_advanced( cblas_lib) endif() if (NOT lapack_found) find_library(lapack_lib NAMES lapack lapack-3 PATHS ${extra_paths}) if (lapack_lib) set(lapack_libraries ${lapack_lib}) set(lapack_found 1) message(STATUS "Found LAPACK library") endif() mark_as_advanced( lapack_lib) endif() # try to find some other BLAS libraries if we didn't find the MKL if (NOT blas_found) find_library(atlas_lib atlas PATHS ${extra_paths}) find_library(cblas_lib cblas PATHS ${extra_paths}) if (atlas_lib AND cblas_lib) set(blas_libraries ${atlas_lib} ${cblas_lib}) set(blas_found 1) message(STATUS "Found ATLAS BLAS library") endif() mark_as_advanced( atlas_lib cblas_lib) endif() # CentOS 7 atlas if (NOT blas_found) find_library(tatlas_lib tatlas PATHS ${extra_paths}) find_library(satlas_lib satlas PATHS ${extra_paths}) if (tatlas_lib AND satlas_lib ) set(blas_libraries ${tatlas_lib} ${satlas_lib}) set(blas_found 1) message(STATUS "Found ATLAS BLAS library") endif() mark_as_advanced( tatlas_lib satlas_lib) endif() if (NOT blas_found) find_library(cblas_lib cblas PATHS ${extra_paths}) if (cblas_lib) set(blas_libraries ${cblas_lib}) set(blas_found 1) message(STATUS "Found CBLAS library") endif() mark_as_advanced( cblas_lib) endif() if (NOT blas_found) find_library(generic_blas blas PATHS ${extra_paths}) if (generic_blas) set(blas_libraries ${generic_blas}) set(blas_found 1) message(STATUS "Found BLAS library") endif() mark_as_advanced( generic_blas) endif() # Make sure we really found a CBLAS library. That is, it needs to expose # the proper cblas link symbols. So here we test if one of them is present # and assume everything is good if it is. Note that we don't do this check if # we found the Intel MKL since for some reason CHECK_FUNCTION_EXISTS doesn't work # with it. But it's fine since the MKL should always have cblas. if (blas_found AND NOT found_intel_mkl) set(CMAKE_REQUIRED_LIBRARIES ${blas_libraries}) CHECK_FUNCTION_EXISTS(cblas_ddot FOUND_BLAS_HAS_CBLAS) if (NOT FOUND_BLAS_HAS_CBLAS) message(STATUS "BLAS library does not have cblas symbols, so dlib will not use BLAS or LAPACK") set(blas_found 0) set(lapack_found 0) endif() endif() elseif(WIN32 AND NOT MINGW) message(STATUS "Searching for BLAS and LAPACK") include(CheckTypeSize) check_type_size( "void*" SIZE_OF_VOID_PTR) if (SIZE_OF_VOID_PTR EQUAL 8) set( mkl_search_path "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/lib/intel64" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/tbb/lib/intel64/vc14" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/lib/intel64" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/intel64/vc14" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/intel64/vc_mt" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/lib/intel64" "C:/Program Files (x86)/Intel/Composer XE/mkl/lib/intel64" "C:/Program Files (x86)/Intel/Composer XE/tbb/lib/intel64/vc14" "C:/Program Files (x86)/Intel/Composer XE/compiler/lib/intel64" "C:/Program Files/Intel/Composer XE/mkl/lib/intel64" "C:/Program Files/Intel/Composer XE/tbb/lib/intel64/vc14" "C:/Program Files/Intel/Composer XE/compiler/lib/intel64" ) set (mkl_redist_path "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/redist/intel64/compiler" ) find_library(mkl_intel mkl_intel_lp64 ${mkl_search_path}) else() set( mkl_search_path "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/lib/ia32" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/tbb/lib/ia32/vc14" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/lib/ia32" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/ia32" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/ia32/vc14" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/tbb/lib/ia32/vc_mt" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/lib/ia32" "C:/Program Files (x86)/Intel/Composer XE/mkl/lib/ia32" "C:/Program Files (x86)/Intel/Composer XE/tbb/lib/ia32/vc14" "C:/Program Files (x86)/Intel/Composer XE/compiler/lib/ia32" "C:/Program Files/Intel/Composer XE/mkl/lib/ia32" "C:/Program Files/Intel/Composer XE/tbb/lib/ia32/vc14" "C:/Program Files/Intel/Composer XE/compiler/lib/ia32" ) set (mkl_redist_path "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/redist/ia32/compiler" ) find_library(mkl_intel mkl_intel_c ${mkl_search_path}) endif() # Get mkl_include_dir set(mkl_include_search_path "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/mkl/include" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries_*/windows/compiler/include" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/include" "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/include" "C:/Program Files (x86)/Intel/Composer XE/mkl/include" "C:/Program Files (x86)/Intel/Composer XE/compiler/include" "C:/Program Files/Intel/Composer XE/mkl/include" "C:/Program Files/Intel/Composer XE/compiler/include" ) find_path(mkl_include_dir mkl_version.h ${mkl_include_search_path}) mark_as_advanced(mkl_include_dir) # Search for the needed libraries from the MKL. find_library(mkl_core mkl_core ${mkl_search_path}) set(mkl_libs ${mkl_intel} ${mkl_core}) mark_as_advanced(mkl_libs mkl_intel mkl_core) if (DLIB_USE_MKL_WITH_TBB) find_library(mkl_tbb_thread mkl_tbb_thread ${mkl_search_path}) find_library(mkl_tbb tbb ${mkl_search_path}) mark_as_advanced(mkl_tbb_thread mkl_tbb) list(APPEND mkl_libs ${mkl_tbb_thread} ${mkl_tbb}) elseif (DLIB_USE_MKL_SEQUENTIAL) find_library(mkl_sequential mkl_sequential ${mkl_search_path}) mark_as_advanced(mkl_sequential) list(APPEND mkl_libs ${mkl_sequential}) else() find_library(mkl_thread mkl_intel_thread ${mkl_search_path}) find_library(mkl_iomp libiomp5md ${mkl_search_path}) mark_as_advanced(mkl_thread mkl_iomp) list(APPEND mkl_libs ${mkl_thread} ${mkl_iomp}) if (mkl_iomp) # See if we can find the dll that goes with this, so we can copy it to # the output folder, since a very large number of windows users don't # understand that they need to add the Intel MKL's folders to their # PATH to use the Intel MKL. They then complain on the dlib forums. # Copying the Intel MKL dlls to the output directory removes the need # to add the Intel MKL to the PATH. find_file(mkl_iomp_dll "libiomp5md.dll" ${mkl_redist_path}) if (mkl_iomp_dll) message(STATUS "FOUND libiomp5md.dll: ${mkl_iomp_dll}") endif() endif() endif() # If we found the MKL if (mkl_intel AND mkl_core AND ((mkl_tbb_thread AND mkl_tbb) OR mkl_sequential OR (mkl_thread AND mkl_iomp))) set(blas_libraries ${mkl_libs}) set(lapack_libraries ${mkl_libs}) set(blas_found 1) set(lapack_found 1) set(found_intel_mkl 1) message(STATUS "Found Intel MKL BLAS/LAPACK library") # Make sure the version of the Intel MKL we found is compatible with # the compiler we are using. One way to do this check is to see if we can # link to it right now. set(CMAKE_REQUIRED_LIBRARIES ${blas_libraries}) CHECK_FUNCTION_EXISTS(cblas_ddot MKL_HAS_CBLAS) if (NOT MKL_HAS_CBLAS) message("BLAS library does not have cblas symbols, so dlib will not use BLAS or LAPACK") set(blas_found 0) set(lapack_found 0) endif() endif() if (found_intel_mkl AND mkl_include_dir) set(found_intel_mkl_headers 1) endif() endif() # When all else fails use CMake's built in functions to find BLAS and LAPACK if (NOT blas_found) find_package(BLAS QUIET) if (${BLAS_FOUND}) set(blas_libraries ${BLAS_LIBRARIES}) set(blas_found 1) if (NOT lapack_found) find_package(LAPACK QUIET) if (${LAPACK_FOUND}) set(lapack_libraries ${LAPACK_LIBRARIES}) set(lapack_found 1) endif() endif() endif() endif() # If using lapack, determine whether to mangle functions if (lapack_found) include(CheckFortranFunctionExists) set(CMAKE_REQUIRED_LIBRARIES ${lapack_libraries}) check_function_exists("sgesv" LAPACK_FOUND_C_UNMANGLED) check_function_exists("sgesv_" LAPACK_FOUND_C_MANGLED) if (CMAKE_Fortran_COMPILER_LOADED) check_fortran_function_exists("sgesv" LAPACK_FOUND_FORTRAN_UNMANGLED) check_fortran_function_exists("sgesv_" LAPACK_FOUND_FORTRAN_MANGLED) endif () if (LAPACK_FOUND_C_MANGLED OR LAPACK_FOUND_FORTRAN_MANGLED) set(lapack_with_underscore 1) elseif (LAPACK_FOUND_C_UNMANGLED OR LAPACK_FOUND_FORTRAN_UNMANGLED) set(lapack_without_underscore 1) endif () endif() if (UNIX OR MINGW) if (NOT blas_found) message(" *****************************************************************************") message(" *** No BLAS library found so using dlib's built in BLAS. However, if you ***") message(" *** install an optimized BLAS such as OpenBLAS or the Intel MKL your code ***") message(" *** will run faster. On Ubuntu you can install OpenBLAS by executing: ***") message(" *** sudo apt-get install libopenblas-dev liblapack-dev ***") message(" *** Or you can easily install OpenBLAS from source by downloading the ***") message(" *** source tar file from http://www.openblas.net, extracting it, and ***") message(" *** running: ***") message(" *** make; sudo make install ***") message(" *****************************************************************************") endif() endif()