1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
8 Find Basic Linear Algebra Subprograms (BLAS) library
10 This module finds an installed Fortran library that implements the
11 `BLAS linear-algebra interface`_.
13 At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled.
15 .. _`BLAS linear-algebra interface`: https://netlib.org/blas/
20 The following variables may be set to influence this module's behavior:
23 if ``ON`` use static linkage
26 Set to one of the :ref:`BLAS/LAPACK Vendors` to search for BLAS only
27 from the specified vendor. If not set, all vendors are considered.
30 if ``ON`` tries to find the BLAS95 interfaces
32 ``BLA_PREFER_PKGCONFIG``
33 .. versionadded:: 3.11
35 if set ``pkg-config`` will be used to search for a BLAS library first
36 and if one is found that is preferred
38 ``BLA_PKGCONFIG_BLAS``
39 .. versionadded:: 3.25
41 If set, the ``pkg-config`` method will look for this module name instead of
44 ``BLA_SIZEOF_INTEGER``
45 .. versionadded:: 3.22
47 Specify the BLAS/LAPACK library integer size:
50 Search for a BLAS/LAPACK with 32-bit integer interfaces.
52 Search for a BLAS/LAPACK with 64-bit integer interfaces.
54 Search for any BLAS/LAPACK.
55 Most likely, a BLAS/LAPACK with 32-bit integer interfaces will be found.
60 This module defines the following :prop_tgt:`IMPORTED` targets:
63 .. versionadded:: 3.18
65 The libraries to use for BLAS, if found.
70 This module defines the following variables:
73 library implementing the BLAS interface is found
75 uncached list of required linker flags (excluding ``-l`` and ``-L``).
77 uncached list of libraries (using full path name) to link against
78 to use BLAS (may be empty if compiler implicitly links BLAS)
80 uncached list of libraries (using full path name) to link against
81 to use BLAS95 interface
83 library implementing the BLAS95 interface is found
85 .. _`BLAS/LAPACK Vendors`:
91 Generic reference implementation
93 ``ACML``, ``ACML_MP``, ``ACML_GPU``
97 Apple BLAS (Accelerate), and Apple NAS (vecLib)
99 ``Arm``, ``Arm_mp``, ``Arm_ilp64``, ``Arm_ilp64_mp``
100 .. versionadded:: 3.18
102 Arm Performance Libraries
105 Automatically Tuned Linear Algebra Software
108 Compaq/Digital Extended Math Library
111 .. versionadded:: 3.20
116 .. versionadded:: 3.11
121 .. versionadded:: 3.19
123 ``Fujitsu_SSL2``, ``Fujitsu_SSL2BLAMP``, ``Fujitsu_SSL2SVE``, ``Fujitsu_SSL2BLAMPSVE``
124 .. versionadded:: 3.20
126 Fujitsu SSL2 serial and parallel blas/lapack with SVE instructions
131 ``IBMESSL``, ``IBMESSL_SMP``
133 IBM Engineering and Scientific Subroutine Library
136 Intel MKL 32 bit and 64 bit obsolete versions
139 Intel MKL v10 32 bit, threaded code
142 Intel MKL v10+ 64 bit, threaded code, lp64 model
145 Intel MKL v10+ 64 bit, sequential code, lp64 model
148 .. versionadded:: 3.13
150 Intel MKL v10+ 64 bit, threaded code, ilp64 model
152 ``Intel10_64ilp_seq``
153 .. versionadded:: 3.13
155 Intel MKL v10+ 64 bit, sequential code, ilp64 model
158 .. versionadded:: 3.17
160 Intel MKL v10+ 64 bit, single dynamic library
163 .. versionadded:: 3.21
168 .. versionadded:: 3.6
171 Portable High Performance ANSI C (PHiPAC)
173 ``SCSL``, ``SCSL_mp``
174 Scientific Computing Software Library
177 SGI Scientific Mathematical Library
180 Sun Performance Library
187 To use the Intel MKL implementation of BLAS, a project must enable at least
188 one of the ``C`` or ``CXX`` languages. Set ``BLA_VENDOR`` to an Intel MKL
189 variant either on the command-line as ``-DBLA_VENDOR=Intel10_64lp`` or in
192 .. code-block:: cmake
194 set(BLA_VENDOR Intel10_64lp)
197 In order to build a project using Intel MKL, and end user must first
198 establish an Intel MKL environment:
201 Source the full Intel environment script:
203 .. code-block:: shell
205 . /opt/intel/oneapi/setvars.sh
207 Or, source the MKL component environment script:
209 .. code-block:: shell
211 . /opt/intel/oneapi/mkl/latest/env/vars.sh
214 Source the full Intel environment script:
216 .. code-block:: shell
218 . /opt/intel/bin/compilervars.sh intel64
220 Or, source the MKL component environment script:
222 .. code-block:: shell
224 . /opt/intel/mkl/bin/mklvars.sh intel64
226 The above environment scripts set the ``MKLROOT`` environment variable
227 to the top of the MKL installation. They also add the location of the
228 runtime libraries to the dynamic library loader environment variable for
229 your platform (e.g. ``LD_LIBRARY_PATH``). This is necessary for programs
230 linked against MKL to run.
234 As of Intel oneAPI 2021.2, loading only the MKL component does not
235 make all of its dependencies available. In particular, the ``iomp5``
236 library must be available separately, or provided by also loading
237 the compiler component environment:
239 .. code-block:: shell
241 . /opt/intel/oneapi/compiler/latest/env/vars.sh
243 #]=======================================================================]
245 # The approach follows that of the ``autoconf`` macro file, ``acx_blas.m4``
246 # (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
248 # Check the language being used
249 if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
250 if(BLAS_FIND_REQUIRED)
251 message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
253 message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)")
258 function(_add_blas_target)
259 if(BLAS_FOUND AND NOT TARGET BLAS::BLAS)
260 add_library(BLAS::BLAS INTERFACE IMPORTED)
262 set_target_properties(BLAS::BLAS PROPERTIES
263 INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}"
266 if(BLAS_LINKER_FLAGS)
267 set_target_properties(BLAS::BLAS PROPERTIES
268 INTERFACE_LINK_OPTIONS "${BLAS_LINKER_FLAGS}"
274 if(CMAKE_Fortran_COMPILER_LOADED)
275 include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
277 include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
279 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
281 if(BLA_PREFER_PKGCONFIG)
282 if(NOT BLA_PKGCONFIG_BLAS)
283 set(BLA_PKGCONFIG_BLAS "blas")
285 find_package(PkgConfig QUIET)
286 pkg_check_modules(PKGC_BLAS QUIET ${BLA_PKGCONFIG_BLAS})
288 set(BLAS_FOUND ${PKGC_BLAS_FOUND})
289 set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}")
295 # TODO: move this stuff to a separate module
297 function(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _deps _addlibdir _subdirs)
298 # This function checks for the existence of the combination of libraries
299 # given by _list. If the combination is found, this checks whether can link
300 # against that library combination using the name of a routine given by _name
301 # using the linker flags given by _flags. If the combination of libraries is
302 # found and passes the link test, ${LIBRARIES} is set to the list of complete
303 # library paths that have been found. Otherwise, ${LIBRARIES} is set to FALSE.
305 set(_libraries_work TRUE)
311 set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
313 set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
316 if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
317 # for ubuntu's libblas3gf and liblapack3gf packages
318 set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
322 set(_extaddlibdir "${_addlibdir}")
324 list(APPEND _extaddlibdir ENV LIB)
326 list(APPEND _extaddlibdir ENV DYLD_LIBRARY_PATH)
328 list(APPEND _extaddlibdir ENV LD_LIBRARY_PATH)
330 list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
332 foreach(_library ${_list})
333 if(_library MATCHES "^-")
334 # Respect linker flags as-is (required by MKL)
335 list(APPEND _libraries "${_library}")
337 string(REGEX REPLACE "[^A-Za-z0-9]" "_" _lib_var "${_library}")
338 string(APPEND _combined_name "_${_lib_var}")
339 if(NOT "${_deps}" STREQUAL "")
340 string(APPEND _combined_name "_deps")
343 find_library(${_prefix}_${_lib_var}_LIBRARY
346 PATHS ${_extaddlibdir}
347 PATH_SUFFIXES ${_subdirs}
349 mark_as_advanced(${_prefix}_${_lib_var}_LIBRARY)
350 list(APPEND _libraries ${${_prefix}_${_lib_var}_LIBRARY})
351 set(_libraries_work ${${_prefix}_${_lib_var}_LIBRARY})
356 foreach(_flag ${_flags})
357 string(REGEX REPLACE "[^A-Za-z0-9]" "_" _flag_var "${_flag}")
358 string(APPEND _combined_name "_${_flag_var}")
361 # Test this combination of libraries.
362 set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${_libraries} ${_deps})
363 set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY})
364 if(CMAKE_Fortran_COMPILER_LOADED)
365 check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
367 check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
369 set(CMAKE_REQUIRED_LIBRARIES)
370 set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
374 if("${_list}" STREQUAL "")
375 set(_libraries "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
377 list(APPEND _libraries ${_deps})
380 set(_libraries FALSE)
382 set(${LIBRARIES} "${_libraries}" PARENT_SCOPE)
385 set(BLAS_LINKER_FLAGS)
387 set(BLAS95_LIBRARIES)
388 set(_blas_fphsa_req_var BLAS_LIBRARIES)
389 if(NOT $ENV{BLA_VENDOR} STREQUAL "")
390 set(BLA_VENDOR $ENV{BLA_VENDOR})
393 set(BLA_VENDOR "All")
397 if(NOT BLA_SIZEOF_INTEGER)
398 # in the reality we do not know which API of BLAS/LAPACK is masked in library
399 set(_blas_sizeof_integer "ANY")
400 elseif((BLA_SIZEOF_INTEGER STREQUAL "ANY") OR
401 (BLA_SIZEOF_INTEGER STREQUAL "4") OR
402 (BLA_SIZEOF_INTEGER STREQUAL "8"))
403 set(_blas_sizeof_integer ${BLA_SIZEOF_INTEGER})
405 message(FATAL_ERROR "BLA_SIZEOF_INTEGER can have only <no value>, ANY, 4, or 8 values")
408 # Implicitly linked BLAS libraries?
409 if(BLA_VENDOR STREQUAL "All")
410 if(NOT BLAS_LIBRARIES)
411 check_blas_libraries(
423 # Give a more helpful "found" message
424 set(BLAS_WORKS "implicitly linked")
425 set(_blas_fphsa_req_var BLAS_WORKS)
429 # BLAS in the Intel MKL 10+ library?
430 if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
431 if(NOT BLAS_LIBRARIES)
432 if(CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
433 # System-specific settings
436 set(BLAS_mkl_DLL_SUFFIX "")
438 set(BLAS_mkl_DLL_SUFFIX "_dll")
442 set(BLAS_mkl_START_GROUP "-Wl,--start-group")
443 set(BLAS_mkl_END_GROUP "-Wl,--end-group")
445 set(BLAS_mkl_START_GROUP "")
446 set(BLAS_mkl_END_GROUP "")
448 # Switch to GNU Fortran support layer if needed (but not on Apple, where MKL does not provide it)
449 if(CMAKE_Fortran_COMPILER_LOADED AND (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "LCC") AND NOT APPLE)
450 set(BLAS_mkl_INTFACE "gf")
451 set(BLAS_mkl_THREADING "gnu")
452 set(BLAS_mkl_OMP "gomp")
454 set(BLAS_mkl_INTFACE "intel")
455 set(BLAS_mkl_THREADING "intel")
456 set(BLAS_mkl_OMP "iomp5")
458 set(BLAS_mkl_LM "-lm")
459 set(BLAS_mkl_LDL "-ldl")
462 if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
463 find_package(Threads)
465 find_package(Threads REQUIRED)
468 if(_blas_sizeof_integer EQUAL 8)
469 set(BLAS_mkl_ILP_MODE "ilp64")
470 elseif(_blas_sizeof_integer EQUAL 4)
471 set(BLAS_mkl_ILP_MODE "lp64")
473 if(BLA_VENDOR MATCHES "_64ilp")
474 set(BLAS_mkl_ILP_MODE "ilp64")
476 set(BLAS_mkl_ILP_MODE "lp64")
480 set(BLAS_SEARCH_LIBS "")
483 set(BLAS_mkl_SEARCH_SYMBOL "sgemm_f95")
484 set(_BLAS_LIBRARIES BLAS95_LIBRARIES)
486 # Find the main file (32-bit or 64-bit)
487 set(BLAS_SEARCH_LIBS_WIN_MAIN "")
488 if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
489 list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
490 "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
493 if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
494 list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
495 "mkl_blas95_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX} mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
498 # Add threading/sequential libs
499 set(BLAS_SEARCH_LIBS_WIN_THREAD "")
500 if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
502 list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
503 "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
505 list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
506 "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
508 if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
509 list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
510 "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
513 # Cartesian product of the above
514 foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
515 foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
516 list(APPEND BLAS_SEARCH_LIBS
517 "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
521 if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
523 list(APPEND BLAS_SEARCH_LIBS
524 "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
527 list(APPEND BLAS_SEARCH_LIBS
528 "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
530 if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
532 list(APPEND BLAS_SEARCH_LIBS
533 "mkl_blas95 mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
536 list(APPEND BLAS_SEARCH_LIBS
537 "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
539 if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
540 list(APPEND BLAS_SEARCH_LIBS
541 "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}")
545 set(BLAS_mkl_SEARCH_SYMBOL sgemm)
546 set(_BLAS_LIBRARIES BLAS_LIBRARIES)
548 # Find the main file (32-bit or 64-bit)
549 set(BLAS_SEARCH_LIBS_WIN_MAIN "")
550 if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
551 list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
552 "mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
554 if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
555 list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
556 "mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
559 # Add threading/sequential libs
560 set(BLAS_SEARCH_LIBS_WIN_THREAD "")
561 if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
562 list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
563 "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
565 if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
567 list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
568 "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
570 list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
571 "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
573 if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
574 list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
575 "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
578 # Cartesian product of the above
579 foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
580 foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
581 list(APPEND BLAS_SEARCH_LIBS
582 "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
586 if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
588 list(APPEND BLAS_SEARCH_LIBS
589 "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
592 list(APPEND BLAS_SEARCH_LIBS
593 "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
595 if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
597 list(APPEND BLAS_SEARCH_LIBS
598 "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
601 list(APPEND BLAS_SEARCH_LIBS
602 "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
604 if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
605 list(APPEND BLAS_SEARCH_LIBS
606 "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}")
609 #older versions of intel mkl libs
610 if(BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
611 list(APPEND BLAS_SEARCH_LIBS
613 list(APPEND BLAS_SEARCH_LIBS
615 list(APPEND BLAS_SEARCH_LIBS
621 if(BLA_VENDOR MATCHES "^Intel10_64_dyn$" OR BLA_VENDOR STREQUAL "All")
622 # mkl >= 10.3 with single dynamic library
623 list(APPEND BLAS_SEARCH_LIBS
627 # MKL uses a multitude of partially platform-specific subdirectories:
628 if(BLA_VENDOR STREQUAL "Intel10_32")
629 set(BLAS_mkl_ARCH_NAME "ia32")
631 set(BLAS_mkl_ARCH_NAME "intel64")
634 set(BLAS_mkl_OS_NAME "win")
636 set(BLAS_mkl_OS_NAME "mac")
638 set(BLAS_mkl_OS_NAME "lin")
640 if(DEFINED ENV{MKLROOT})
641 file(TO_CMAKE_PATH "$ENV{MKLROOT}" BLAS_mkl_MKLROOT)
642 # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
643 # so we can better detect other relevant libraries in 'compiler' or 'tbb':
644 get_filename_component(BLAS_mkl_MKLROOT_LAST_DIR "${BLAS_mkl_MKLROOT}" NAME)
645 if(BLAS_mkl_MKLROOT_LAST_DIR STREQUAL "mkl")
646 get_filename_component(BLAS_mkl_MKLROOT "${BLAS_mkl_MKLROOT}" DIRECTORY)
649 set(BLAS_mkl_LIB_PATH_SUFFIXES
650 "compiler/lib" "compiler/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
651 "compiler/lib/${BLAS_mkl_ARCH_NAME}"
652 "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
653 "mkl/lib/${BLAS_mkl_ARCH_NAME}"
654 "lib" "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
655 "lib/${BLAS_mkl_ARCH_NAME}"
658 foreach(_search ${BLAS_SEARCH_LIBS})
659 string(REPLACE " " ";" _search ${_search})
660 if(NOT ${_BLAS_LIBRARIES})
661 check_blas_libraries(
664 ${BLAS_mkl_SEARCH_SYMBOL}
667 "${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}"
668 "${BLAS_mkl_MKLROOT}"
669 "${BLAS_mkl_LIB_PATH_SUFFIXES}"
675 unset(BLAS_mkl_ILP_MODE)
676 unset(BLAS_mkl_INTFACE)
677 unset(BLAS_mkl_THREADING)
679 unset(BLAS_mkl_DLL_SUFFIX)
682 unset(BLAS_mkl_MKLROOT)
683 unset(BLAS_mkl_MKLROOT_LAST_DIR)
684 unset(BLAS_mkl_ARCH_NAME)
685 unset(BLAS_mkl_OS_NAME)
686 unset(BLAS_mkl_LIB_PATH_SUFFIXES)
692 find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS95_LIBRARIES)
693 set(BLAS95_FOUND ${BLAS_FOUND})
695 set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}")
699 # gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
700 if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
701 if(NOT BLAS_LIBRARIES)
702 check_blas_libraries(
715 # FlexiBLAS? (http://www.mpi-magdeburg.mpg.de/mpcsc/software/FlexiBLAS/)
716 if(BLA_VENDOR STREQUAL "FlexiBLAS" OR BLA_VENDOR STREQUAL "All")
717 set(_blas_flexiblas_lib "flexiblas")
719 if(_blas_sizeof_integer EQUAL 8)
720 string(APPEND _blas_flexiblas_lib "64")
723 if(NOT BLAS_LIBRARIES)
724 check_blas_libraries(
729 "${_blas_flexiblas_lib}"
736 unset(_blas_flexiblas_lib)
739 # OpenBLAS? (http://www.openblas.net)
740 if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
741 set(_blas_openblas_lib "openblas")
743 if(_blas_sizeof_integer EQUAL 8)
744 string(APPEND _blas_openblas_lib "64")
747 if(NOT BLAS_LIBRARIES)
748 check_blas_libraries(
753 "${_blas_openblas_lib}"
759 if(NOT BLAS_LIBRARIES AND (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED))
760 if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
761 find_package(Threads)
763 find_package(Threads REQUIRED)
765 set(_threadlibs "${CMAKE_THREAD_LIBS_INIT}")
767 if (CMAKE_C_COMPILER_LOADED)
768 find_package(OpenMP QUIET COMPONENTS C)
769 list(PREPEND _threadlibs "${OpenMP_C_LIBRARIES}")
770 elseif(CMAKE_CXX_COMPILER_LOADED)
771 find_package(OpenMP QUIET COMPONENTS CXX)
772 list(PREPEND _threadlibs "${OpenMP_CXX_LIBRARIES}")
775 check_blas_libraries(
780 "${_blas_openblas_lib}"
788 unset(_blas_openblas_lib)
791 # ArmPL blas library? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
792 if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All")
794 # Check for 64bit Integer support
795 if(_blas_sizeof_integer EQUAL 8)
796 set(_blas_armpl_lib "armpl_ilp64")
797 elseif(_blas_sizeof_integer EQUAL 4)
798 set(_blas_armpl_lib "armpl_lp64")
800 if(BLA_VENDOR MATCHES "_ilp64")
801 set(_blas_armpl_lib "armpl_ilp64")
803 set(_blas_armpl_lib "armpl_lp64")
807 # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
808 if(BLA_VENDOR MATCHES "_mp")
809 string(APPEND _blas_armpl_lib "_mp")
812 if(NOT BLAS_LIBRARIES)
813 check_blas_libraries(
824 unset(_blas_armpl_lib)
827 # FLAME's blis library? (https://github.com/flame/blis)
828 if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
829 set(_blas_flame_lib "blis")
831 if(_blas_sizeof_integer EQUAL 8)
832 string(APPEND _blas_flame_lib "64")
835 if(NOT BLAS_LIBRARIES)
836 check_blas_libraries(
848 unset(_blas_flame_lib)
851 # BLAS in the ATLAS library? (http://math-atlas.sourceforge.net/)
852 if(BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
853 if(NOT BLAS_LIBRARIES)
854 check_blas_libraries(
867 # BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
868 if(BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
869 if(NOT BLAS_LIBRARIES)
870 check_blas_libraries(
883 # BLAS in Alpha CXML library?
884 if(BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
885 if(_blas_sizeof_integer EQUAL 8)
886 if(BLA_VENDOR STREQUAL "CXML")
887 message(FATAL_ERROR "CXML does not support Int64 type")
890 if(NOT BLAS_LIBRARIES)
891 check_blas_libraries(
905 # BLAS in Alpha DXML library? (now called CXML, see above)
906 if(BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
907 if(_blas_sizeof_integer EQUAL 8)
908 if(BLA_VENDOR STREQUAL "DXML")
909 message(FATAL_ERROR "DXML does not support Int64 type")
912 if(NOT BLAS_LIBRARIES)
913 check_blas_libraries(
927 # BLAS in Sun Performance library?
928 if(BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
929 if(NOT BLAS_LIBRARIES)
930 check_blas_libraries(
941 set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
946 # BLAS in SCSL library? (SGI/Cray Scientific Library)
947 if(BLA_VENDOR MATCHES "SCSL" OR BLA_VENDOR STREQUAL "All")
948 set(_blas_scsl_lib "scs")
950 if(_blas_sizeof_integer EQUAL 8)
951 string(APPEND _blas_scsl_lib "_i8")
953 if(BLA_VENDOR MATCHES "_mp")
954 string(APPEND _blas_scsl_lib "_mp")
957 if(NOT BLAS_LIBRARIES)
958 check_blas_libraries(
970 unset(_blas_scsl_lib)
973 # BLAS in SGIMATH library?
974 if(BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
975 if(NOT BLAS_LIBRARIES)
976 check_blas_libraries(
989 # BLAS in IBM ESSL library?
990 if(BLA_VENDOR MATCHES "IBMESSL" OR BLA_VENDOR STREQUAL "All")
991 set(_blas_essl_lib "essl")
993 if(BLA_VENDOR MATCHES "_SMP")
994 string(APPEND _blas_essl_lib "smp")
996 if(_blas_sizeof_integer EQUAL 8)
997 string(APPEND _blas_essl_lib "6464")
1000 if(NOT BLAS_LIBRARIES)
1001 check_blas_libraries(
1013 unset(_blas_essl_lib)
1016 # BLAS in acml library?
1017 if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
1018 if(((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
1019 ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
1020 ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))
1022 # try to find acml in "standard" paths
1024 file(GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt")
1026 file(GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt")
1029 file(GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples")
1031 file(GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples")
1033 list(GET _ACML_ROOT 0 _ACML_ROOT)
1034 list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
1036 get_filename_component(_ACML_ROOT ${_ACML_ROOT} PATH)
1037 if(_blas_sizeof_integer EQUAL 8)
1038 set(_ACML_PATH_SUFFIX "_int64")
1040 set(_ACML_PATH_SUFFIX "")
1042 if(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
1043 set(_ACML_COMPILER32 "ifort32")
1044 set(_ACML_COMPILER64 "ifort64")
1045 elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM")
1046 # 32-bit not supported
1047 set(_ACML_COMPILER64 "ifx")
1048 elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro")
1049 set(_ACML_COMPILER32 "sun32")
1050 set(_ACML_COMPILER64 "sun64")
1051 elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "PGI")
1052 set(_ACML_COMPILER32 "pgi32")
1054 set(_ACML_COMPILER64 "win64")
1056 set(_ACML_COMPILER64 "pgi64")
1058 elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Open64")
1059 # 32 bit builds not supported on Open64 but for code simplicity
1060 # We'll just use the same directory twice
1061 set(_ACML_COMPILER32 "open64_64")
1062 set(_ACML_COMPILER64 "open64_64")
1063 elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "NAG")
1064 set(_ACML_COMPILER32 "nag32")
1065 set(_ACML_COMPILER64 "nag64")
1067 set(_ACML_COMPILER32 "gfortran32")
1068 set(_ACML_COMPILER64 "gfortran64")
1071 if(BLA_VENDOR STREQUAL "ACML_MP")
1072 set(_ACML_MP_LIB_DIRS
1073 "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
1074 "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib")
1077 "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
1078 "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib")
1081 elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
1082 set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
1085 if(BLA_VENDOR STREQUAL "ACML_MP")
1086 foreach(BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
1087 check_blas_libraries(
1091 "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} ""
1097 elseif(BLA_VENDOR STREQUAL "ACML_GPU")
1098 foreach(BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
1099 check_blas_libraries(
1103 "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} ""
1110 foreach(BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS})
1111 check_blas_libraries(
1115 "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} ""
1123 # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
1124 if(NOT BLAS_LIBRARIES)
1125 check_blas_libraries(
1136 if(NOT BLAS_LIBRARIES)
1137 check_blas_libraries(
1148 if(NOT BLAS_LIBRARIES)
1149 check_blas_libraries(
1154 "acml;acml_mv;CALBLAS"
1162 # Apple BLAS library?
1163 if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
1164 if(_blas_sizeof_integer EQUAL 8)
1165 if(BLA_VENDOR STREQUAL "Apple")
1166 message(FATAL_ERROR "Accelerate Framework does not support Int64 type")
1169 if(NOT BLAS_LIBRARIES)
1170 check_blas_libraries(
1184 # Apple NAS (vecLib) library?
1185 if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
1186 if(_blas_sizeof_integer EQUAL 8)
1187 if(BLA_VENDOR STREQUAL "NAS")
1188 message(FATAL_ERROR "Accelerate Framework does not support Int64 type")
1191 if(NOT BLAS_LIBRARIES)
1192 check_blas_libraries(
1206 # Elbrus Math Library?
1207 if(BLA_VENDOR MATCHES "EML" OR BLA_VENDOR STREQUAL "All")
1209 set(_blas_eml_lib "eml")
1211 if(_blas_sizeof_integer EQUAL 8)
1212 string(APPEND _blas_eml_lib "_ilp64")
1214 # Check for OpenMP support, VIA BLA_VENDOR of eml_mt
1215 if(BLA_VENDOR MATCHES "_mt")
1216 string(APPEND _blas_eml_lib "_mt")
1219 if(NOT BLAS_LIBRARIES)
1220 check_blas_libraries(
1231 unset(_blas_eml_lib)
1234 # Fujitsu SSL2 Library?
1235 if(NOT BLAS_LIBRARIES
1236 AND (BLA_VENDOR MATCHES "^Fujitsu_SSL2" OR BLA_VENDOR STREQUAL "All"))
1237 set(_blas_fjlapack_lib "fjlapack")
1238 set(_blas_fjlapack_flags "-Kopenmp")
1240 if(BLA_VENDOR MATCHES "BLAMP")
1241 string(APPEND _blas_fjlapack_lib "ex")
1243 if(BLA_VENDOR MATCHES "SVE")
1244 string(APPEND _blas_fjlapack_lib "sve")
1246 if(_blas_sizeof_integer EQUAL 8)
1247 string(APPEND _blas_fjlapack_lib "_ilp64")
1250 if(NOT BLAS_LIBRARIES)
1251 check_blas_libraries(
1255 "${_blas_fjlapack_flags}"
1256 "${_blas_fjlapack_lib}"
1262 set(BLAS_LINKER_FLAGS ${_blas_fjlapack_flags})
1266 unset(_blas_fjlapack_flags)
1267 unset(_blas_fjlapack_lib)
1270 # BLAS in nVidia HPC SDK? (https://developer.nvidia.com/hpc-sdk)
1271 if(BLA_VENDOR STREQUAL "NVHPC" OR BLA_VENDOR STREQUAL "All")
1272 set(_blas_nvhpc_lib "blas")
1274 if(_blas_sizeof_integer EQUAL 8)
1275 string(APPEND _blas_nvhpc_lib "_ilp64")
1276 elseif(_blas_sizeof_integer EQUAL 4)
1277 string(APPEND _blas_nvhpc_lib "_lp64")
1280 if(NOT BLAS_LIBRARIES)
1281 check_blas_libraries(
1286 "${_blas_nvhpc_lib}"
1293 # an additional check for NVHPC 2020
1294 # which does not have differentiation
1295 # between lp64 and ilp64 modes
1296 if(NOT BLAS_LIBRARIES AND NOT _blas_sizeof_integer EQUAL 8)
1297 set(_blas_nvhpc_lib "blas")
1299 check_blas_libraries(
1304 "${_blas_nvhpc_lib}"
1311 unset(_blas_nvhpc_lib)
1314 # Generic BLAS library?
1315 if(BLA_VENDOR STREQUAL "Generic" OR
1316 BLA_VENDOR STREQUAL "All")
1317 set(_blas_generic_lib "blas")
1319 if(_blas_sizeof_integer EQUAL 8)
1320 string(APPEND _blas_generic_lib "64")
1323 if(NOT BLAS_LIBRARIES)
1324 check_blas_libraries(
1329 "${_blas_generic_lib}"
1336 unset(_blas_generic_lib)
1339 # On compilers that implicitly link BLAS (i.e. CrayPrgEnv) we used a
1340 # placeholder for empty BLAS_LIBRARIES to get through our logic above.
1341 if(BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
1342 set(BLAS_LIBRARIES "")
1346 find_package_handle_standard_args(BLAS REQUIRED_VARS ${_blas_fphsa_req_var})
1350 unset(_blas_fphsa_req_var)
1351 unset(_blas_sizeof_integer)
1352 unset(_BLAS_LIBRARIES)