diff options
Diffstat (limited to 'Modules/FindBLAS.cmake')
-rw-r--r-- | Modules/FindBLAS.cmake | 394 |
1 files changed, 251 insertions, 143 deletions
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index b4650b2..e048318 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -8,11 +8,11 @@ FindBLAS Find Basic Linear Algebra Subprograms (BLAS) library This module finds an installed Fortran library that implements the -BLAS linear-algebra interface (see http://www.netlib.org/blas/). +`BLAS linear-algebra interface`_. -The approach follows that taken for the ``autoconf`` macro file, -``acx_blas.m4`` (distributed at -http://ac-archive.sourceforge.net/ac-archive/acx_blas.html). +At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled. + +.. _`BLAS linear-algebra interface`: http://www.netlib.org/blas/ Input Variables ^^^^^^^^^^^^^^^ @@ -23,61 +23,8 @@ The following variables may be set to influence this module's behavior: if ``ON`` use static linkage ``BLA_VENDOR`` - If set, checks only the specified vendor, if not set checks all the - possibilities. List of vendors valid in this module: - - * ``Goto`` - * ``FlexiBLAS`` - * ``OpenBLAS`` - * ``FLAME`` - * ``ATLAS PhiPACK`` - * ``CXML`` - * ``DXML`` - * ``SunPerf`` - * ``SCSL`` - * ``SGIMATH`` - * ``IBMESSL`` - * ``Intel10_32`` (intel mkl v10 32 bit, threaded code) - * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model) - * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model) - * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model) - * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model) - * ``Intel10_64_dyn`` (intel mkl v10+ 64 bit, single dynamic library) - * ``Intel`` (obsolete versions of mkl 32 and 64 bit) - * ``ACML`` - * ``ACML_MP`` - * ``ACML_GPU`` - * ``Apple`` - * ``NAS`` - * ``Arm`` - * ``Arm_mp`` - * ``Arm_ilp64`` - * ``Arm_ilp64_mp`` - * ``EML`` - * ``EML_mt`` - * ``Generic`` - - .. versionadded:: 3.6 - ``OpenBLAS`` support. - - .. versionadded:: 3.11 - ``FLAME`` support. - - .. versionadded:: 3.13 - Added ILP64 MKL variants (``Intel10_64ilp``, ``Intel10_64ilp_seq``). - - .. versionadded:: 3.17 - Added single dynamic library MKL variant (``Intel10_64_dyn``). - - .. versionadded:: 3.18 - Arm Performance Libraries support (``Arm``, ``Arm_mp``, ``Arm_ilp64``, - ``Arm_ilp64_mp``). - - .. versionadded:: 3.19 - ``FlexiBLAS`` support. - - .. versionadded:: 3.20 - Elbrus Math Library support (``EML``, ``EML_mt``). + Set to one of the :ref:`BLAS/LAPACK Vendors` to search for BLAS only + from the specified vendor. If not set, all vendors are considered. ``BLA_F95`` if ``ON`` tries to find the BLAS95 interfaces @@ -91,13 +38,12 @@ The following variables may be set to influence this module's behavior: Imported targets ^^^^^^^^^^^^^^^^ -.. versionadded:: 3.18 - -This module defines the following :prop_tgt:`IMPORTED` target: +This module defines the following :prop_tgt:`IMPORTED` targets: ``BLAS::BLAS`` - The libraries to use for BLAS, if found. + .. versionadded:: 3.18 + The libraries to use for BLAS, if found. Result Variables ^^^^^^^^^^^^^^^^ @@ -117,31 +63,168 @@ This module defines the following variables: ``BLAS95_FOUND`` library implementing the BLAS95 interface is found -.. note:: +.. _`BLAS/LAPACK Vendors`: + +BLAS/LAPACK Vendors +^^^^^^^^^^^^^^^^^^^ + +``Generic`` + Generic reference implementation + +``ACML``, ``ACML_MP``, ``ACML_GPU`` + AMD Core Math Library + +``Apple``, ``NAS`` + Apple BLAS (Accelerate), and Apple NAS (vecLib) + +``Arm``, ``Arm_mp``, ``Arm_ilp64``, ``Arm_ilp64_mp`` + .. versionadded:: 3.18 + + Arm Performance Libraries + +``ATLAS`` + Automatically Tuned Linear Algebra Software + +``CXML``, ``DXML`` + Compaq/Digital Extended Math Library + +``EML``, ``EML_mt`` + .. versionadded:: 3.20 + + Elbrus Math Library + +``FLAME`` + .. versionadded:: 3.11 + + BLIS Framework + +``FlexiBLAS`` + .. versionadded:: 3.19 + +``Fujitsu_SSL2``, ``Fujitsu_SSL2BLAMP`` + .. versionadded:: 3.20 + + Fujitsu SSL2 serial and parallel blas/lapack + +``Goto`` + GotoBLAS + +``IBMESSL`` + IBM Engineering and Scientific Subroutine Library + +``Intel`` + Intel MKL 32 bit and 64 bit obsolete versions + +``Intel10_32`` + Intel MKL v10 32 bit, threaded code + +``Intel10_64lp`` + Intel MKL v10+ 64 bit, threaded code, lp64 model + +``Intel10_64lp_seq`` + Intel MKL v10+ 64 bit, sequential code, lp64 model + +``Intel10_64ilp`` + .. versionadded:: 3.13 + + Intel MKL v10+ 64 bit, threaded code, ilp64 model + +``Intel10_64ilp_seq`` + .. versionadded:: 3.13 + + Intel MKL v10+ 64 bit, sequential code, ilp64 model + +``Intel10_64_dyn`` + .. versionadded:: 3.17 + + Intel MKL v10+ 64 bit, single dynamic library + +``NVHPC`` + .. versionadded:: 3.21 + + NVIDIA HPC SDK + +``OpenBLAS`` + .. versionadded:: 3.6 + +``PhiPACK`` + Portable High Performance ANSI C (PHiPAC) + +``SCSL`` + Scientific Computing Software Library - C, CXX or Fortran must be enabled to detect a BLAS library. - C or CXX must be enabled to use Intel Math Kernel Library (MKL). +``SGIMATH`` + SGI Scientific Mathematical Library - For example, to use Intel MKL libraries and/or Intel compiler: +``SunPerf`` + Sun Performance Library - .. code-block:: cmake +.. _`Intel MKL`: - set(BLA_VENDOR Intel10_64lp) - find_package(BLAS) +Intel MKL +^^^^^^^^^ -Hints -^^^^^ +To use the Intel MKL implementation of BLAS, a project must enable at least +one of the ``C`` or ``CXX`` languages. Set ``BLA_VENDOR`` to an Intel MKL +variant either on the command-line as ``-DBLA_VENDOR=Intel10_64lp`` or in +project code: -``MKLROOT`` - .. versionadded:: 3.15 +.. code-block:: cmake - Set this environment variable to a directory that contains an MKL - installation, or add the directory to the dynamic library loader environment - variable for your platform (``LIB``, ``DYLD_LIBRARY_PATH`` or - ``LD_LIBRARY_PATH``). + set(BLA_VENDOR Intel10_64lp) + find_package(BLAS) + +In order to build a project using Intel MKL, and end user must first +establish an Intel MKL environment: + +Intel oneAPI + Source the full Intel environment script: + + .. code-block:: shell + + . /opt/intel/oneapi/setvars.sh + + Or, source the MKL component environment script: + + .. code-block:: shell + + . /opt/intel/oneapi/mkl/latest/env/vars.sh + +Intel Classic + Source the full Intel environment script: + + .. code-block:: shell + + . /opt/intel/bin/compilervars.sh intel64 + + Or, source the MKL component environment script: + + .. code-block:: shell + + . /opt/intel/mkl/bin/mklvars.sh intel64 + +The above environment scripts set the ``MKLROOT`` environment variable +to the top of the MKL installation. They also add the location of the +runtime libraries to the dynamic library loader environment variable for +your platform (e.g. ``LD_LIBRARY_PATH``). This is necessary for programs +linked against MKL to run. + +.. note:: + + As of Intel oneAPI 2021.2, loading only the MKL component does not + make all of its dependencies available. In particular, the ``iomp5`` + library must be available separately, or provided by also loading + the compiler component environment: + + .. code-block:: shell + + . /opt/intel/oneapi/compiler/latest/env/vars.sh #]=======================================================================] +# The approach follows that of the ``autoconf`` macro file, ``acx_blas.m4`` +# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_blas.html). + # Check the language being used if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED)) if(BLAS_FIND_REQUIRED) @@ -153,13 +236,18 @@ if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_CO endif() function(_add_blas_target) - if(NOT TARGET BLAS::BLAS) + if(BLAS_FOUND AND NOT TARGET BLAS::BLAS) add_library(BLAS::BLAS INTERFACE IMPORTED) if(BLAS_LIBRARIES) set_target_properties(BLAS::BLAS PROPERTIES INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}" ) endif() + if(BLAS_LINKER_FLAGS) + set_target_properties(BLAS::BLAS PROPERTIES + INTERFACE_LINK_OPTIONS "${BLAS_LINKER_FLAGS}" + ) + endif() endif() endfunction() @@ -168,10 +256,7 @@ if(CMAKE_Fortran_COMPILER_LOADED) else() include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake) endif() -include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -cmake_push_check_state() -set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY}) if(BLA_PREFER_PKGCONFIG) find_package(PkgConfig) @@ -184,40 +269,33 @@ if(BLA_PREFER_PKGCONFIG) endif() endif() -set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) -if(BLA_STATIC) - if(WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else() - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif() -else() - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif() -endif() - # TODO: move this stuff to a separate module -macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs) - # This macro checks for the existence of the combination of fortran libraries - # given by _list. If the combination is found, this macro checks (using the - # Check_Fortran_Function_Exists macro) whether can link against that library - # combination using the name of a routine given by _name using the linker - # flags given by _flags. If the combination of libraries is found and passes - # the link test, LIBRARIES is set to the list of complete library paths that - # have been found. Otherwise, LIBRARIES is set to FALSE. - - # N.B. _prefix is the prefix applied to the names of all cached variables that - # are generated internally and marked advanced by this macro. - # _addlibdir is a list of additional search paths. _subdirs is a list of path - # suffixes to be used by find_library(). +function(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _deps _addlibdir _subdirs) + # This function checks for the existence of the combination of libraries + # given by _list. If the combination is found, this checks whether can link + # against that library combination using the name of a routine given by _name + # using the linker flags given by _flags. If the combination of libraries is + # found and passes the link test, ${LIBRARIES} is set to the list of complete + # library paths that have been found. Otherwise, ${LIBRARIES} is set to FALSE. set(_libraries_work TRUE) - set(${LIBRARIES}) + set(_libraries) set(_combined_name) + if(BLA_STATIC) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() + else() + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif() + endif() + set(_extaddlibdir "${_addlibdir}") if(WIN32) list(APPEND _extaddlibdir ENV LIB) @@ -229,33 +307,37 @@ macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _add list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") foreach(_library ${_list}) - if(_library MATCHES "^-Wl,--(start|end)-group$") - # Respect linker flags like --start/end-group (required by MKL) - set(${LIBRARIES} ${${LIBRARIES}} "${_library}") + if(_library MATCHES "^-") + # Respect linker flags as-is (required by MKL) + list(APPEND _libraries "${_library}") else() - set(_combined_name ${_combined_name}_${_library}) - if(NOT "${_threadlibs}" STREQUAL "") - set(_combined_name ${_combined_name}_threadlibs) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _lib_var "${_library}") + set(_combined_name ${_combined_name}_${_lib_var}) + if(NOT "${_deps}" STREQUAL "") + set(_combined_name ${_combined_name}_deps) endif() if(_libraries_work) - find_library(${_prefix}_${_library}_LIBRARY + find_library(${_prefix}_${_lib_var}_LIBRARY NAMES ${_library} NAMES_PER_DIR PATHS ${_extaddlibdir} PATH_SUFFIXES ${_subdirs} ) - #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}") - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + mark_as_advanced(${_prefix}_${_lib_var}_LIBRARY) + list(APPEND _libraries ${${_prefix}_${_lib_var}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_lib_var}_LIBRARY}) endif() endif() endforeach() + foreach(_flag ${_flags}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" _flag_var "${_flag}") + set(_combined_name ${_combined_name}_${_flag_var}) + endforeach() if(_libraries_work) # Test this combination of libraries. - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threadlibs}) - #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${_libraries} ${_deps}) + set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY}) if(CMAKE_Fortran_COMPILER_LOADED) check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) else() @@ -267,19 +349,20 @@ macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _add if(_libraries_work) if("${_list}" STREQUAL "") - set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + set(_libraries "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES") else() - set(${LIBRARIES} ${${LIBRARIES}} ${_threadlibs}) + list(APPEND _libraries ${_deps}) endif() else() - set(${LIBRARIES} FALSE) + set(_libraries FALSE) endif() - #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") -endmacro() + set(${LIBRARIES} "${_libraries}" PARENT_SCOPE) +endfunction() set(BLAS_LINKER_FLAGS) set(BLAS_LIBRARIES) set(BLAS95_LIBRARIES) +set(_blas_fphsa_req_var BLAS_LIBRARIES) if(NOT $ENV{BLA_VENDOR} STREQUAL "") set(BLA_VENDOR $ENV{BLA_VENDOR}) else() @@ -302,6 +385,9 @@ if(BLA_VENDOR STREQUAL "All") "" ) endif() + if(BLAS_WORKS) + set(_blas_fphsa_req_var BLAS_WORKS) + endif() endif() # BLAS in the Intel MKL 10+ library? @@ -523,7 +609,9 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") "compiler/lib/${BLAS_mkl_ARCH_NAME}" "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}" "mkl/lib/${BLAS_mkl_ARCH_NAME}" - "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}") + "lib" "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}" + "lib/${BLAS_mkl_ARCH_NAME}" + ) foreach(IT ${BLAS_SEARCH_LIBS}) string(REPLACE " " ";" SEARCH_LIBS ${IT}) @@ -619,8 +707,6 @@ if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") endif() set(_threadlibs "${CMAKE_THREAD_LIBS_INIT}") if(BLA_STATIC) - set(_blas_STATIC_CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_FIND_LIBRARY_SUFFIXES}") - set(CMAKE_FIND_LIBRARY_SUFFIXES "${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}") if (CMAKE_C_COMPILER_LOADED) find_package(OpenMP COMPONENTS C) list(PREPEND _threadlibs "${OpenMP_C_LIBRARIES}") @@ -628,8 +714,6 @@ if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All") find_package(OpenMP COMPONENTS CXX) list(PREPEND _threadlibs "${OpenMP_CXX_LIBRARIES}") endif() - set(CMAKE_FIND_LIBRARY_SUFFIXES "${_blas_STATIC_CMAKE_FIND_LIBRARY_SUFFIXES}") - unset(_blas_STATIC_CMAKE_FIND_LIBRARY_SUFFIXES) endif() check_blas_libraries( BLAS_LIBRARIES @@ -1025,8 +1109,35 @@ if(BLA_VENDOR MATCHES "EML" OR BLA_VENDOR STREQUAL "All") endif() +# Fujitsu SSL2 Library? +if(NOT BLAS_LIBRARIES AND + BLA_VENDOR MATCHES "Fujitsu_SSL2" OR BLA_VENDOR STREQUAL "All") + if(BLA_VENDOR STREQUAL "Fujitsu_SSL2BLAMP") + set(_ssl2_suffix BLAMP) + else() + set(_ssl2_suffix) + endif() + check_blas_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "-SSL2${_ssl2_suffix}" + "" + "" + "" + "" + ) + if(BLAS_LIBRARIES) + set(BLAS_LINKER_FLAGS "-SSL2${_ssl2_suffix}") + set(_blas_fphsa_req_var BLAS_LINKER_FLAGS) + endif() + unset(_ssl2_suffix) +endif() + # Generic BLAS library? -if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") +if(BLA_VENDOR STREQUAL "Generic" OR + BLA_VENDOR STREQUAL "NVHPC" OR + BLA_VENDOR STREQUAL "All") if(NOT BLAS_LIBRARIES) check_blas_libraries( BLAS_LIBRARIES @@ -1041,17 +1152,14 @@ if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") endif() endif() -if(NOT BLA_F95) - find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES) -endif() - - -# On compilers that implicitly link BLAS (such as ftn, cc, and CC on Cray HPC machines) -# we used a placeholder for empty BLAS_LIBRARIES to get through our logic above. +# On compilers that implicitly link BLAS (i.e. CrayPrgEnv) we used a +# placeholder for empty BLAS_LIBRARIES to get through our logic above. if(BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") set(BLAS_LIBRARIES "") endif() +if(NOT BLA_F95) + find_package_handle_standard_args(BLAS REQUIRED_VARS ${_blas_fphsa_req_var}) +endif() + _add_blas_target() -cmake_pop_check_state() -set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) |