FindLAPACK.cmake 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file LICENSE.rst or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. FindLAPACK
  5. ----------
  6. Finds the installed Linear Algebra PACKage (LAPACK) Fortran library that
  7. implements the `LAPACK linear-algebra interface`_:
  8. .. code-block:: cmake
  9. find_package(LAPACK [...])
  10. At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled.
  11. .. _`LAPACK linear-algebra interface`: https://netlib.org/lapack/
  12. Imported Targets
  13. ^^^^^^^^^^^^^^^^
  14. This module provides the following :ref:`Imported Targets`:
  15. ``LAPACK::LAPACK``
  16. .. versionadded:: 3.18
  17. Target encapsulating the LAPACK usage requirements, available only if
  18. LAPACK is found.
  19. Result Variables
  20. ^^^^^^^^^^^^^^^^
  21. This module defines the following variables:
  22. ``LAPACK_FOUND``
  23. Boolean indicating whether the library implementing the LAPACK interface
  24. was found.
  25. ``LAPACK_LINKER_FLAGS``
  26. Uncached list of required linker flags (excluding ``-l`` and ``-L``).
  27. ``LAPACK_LIBRARIES``
  28. Uncached list of libraries (using full path name) to link against to use
  29. LAPACK.
  30. ``LAPACK95_LIBRARIES``
  31. Uncached list of libraries (using full path name) to link against to use
  32. LAPACK95.
  33. ``LAPACK95_FOUND``
  34. Boolean indicating whether the library implementing the LAPACK95 interface
  35. was found.
  36. Input Variables
  37. ^^^^^^^^^^^^^^^
  38. The following variables may be set to influence this module's behavior:
  39. ``BLA_STATIC``
  40. If ``ON``, the static linkage will be used.
  41. ``BLA_VENDOR``
  42. Set to one of the :ref:`BLAS/LAPACK Vendors` to search for BLAS only
  43. from the specified vendor. If not set, all vendors are considered.
  44. ``BLA_F95``
  45. If ``ON``, the module tries to find the BLAS95/LAPACK95 interfaces.
  46. ``BLA_PREFER_PKGCONFIG``
  47. .. versionadded:: 3.20
  48. If set, ``pkg-config`` will be used to search for a LAPACK library first
  49. and if one is found that is preferred.
  50. ``BLA_PKGCONFIG_LAPACK``
  51. .. versionadded:: 3.25
  52. If set, the ``pkg-config`` method will look for this module name instead of
  53. just ``lapack``.
  54. ``BLA_SIZEOF_INTEGER``
  55. .. versionadded:: 3.22
  56. Specify the BLAS/LAPACK library integer size:
  57. ``4``
  58. Search for a BLAS/LAPACK with 32-bit integer interfaces.
  59. ``8``
  60. Search for a BLAS/LAPACK with 64-bit integer interfaces.
  61. ``ANY``
  62. Search for any BLAS/LAPACK.
  63. Most likely, a BLAS/LAPACK with 32-bit integer interfaces will be found.
  64. ``BLA_THREAD``
  65. .. versionadded:: 4.1
  66. Specify the BLAS/LAPACK threading model:
  67. ``SEQ``
  68. Sequential model
  69. ``OMP``
  70. OpenMP model
  71. ``ANY``
  72. Search for any BLAS/LAPACK, if both are available most likely ``OMP`` will
  73. be found.
  74. This is currently only supported by NVIDIA NVPL.
  75. Intel MKL
  76. ^^^^^^^^^
  77. To use the Intel MKL implementation of LAPACK, a project must enable at least
  78. one of the ``C`` or ``CXX`` languages. Set ``BLA_VENDOR`` to an Intel MKL
  79. variant either on the command-line as ``-DBLA_VENDOR=Intel10_64lp`` or in
  80. project code:
  81. .. code-block:: cmake
  82. set(BLA_VENDOR Intel10_64lp)
  83. find_package(LAPACK)
  84. In order to build a project using Intel MKL, and end user must first
  85. establish an Intel MKL environment. See the :module:`FindBLAS` module
  86. section on :ref:`Intel MKL` for details.
  87. Examples
  88. ^^^^^^^^
  89. Finding LAPACK and linking it to a project target:
  90. .. code-block:: cmake
  91. find_package(LAPACK)
  92. target_link_libraries(project_target PRIVATE LAPACK::LAPACK)
  93. #]=======================================================================]
  94. # The approach follows that of the ``autoconf`` macro file, ``acx_lapack.m4``
  95. # (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
  96. if(CMAKE_Fortran_COMPILER_LOADED)
  97. include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
  98. else()
  99. include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
  100. endif()
  101. include(FindPackageHandleStandardArgs)
  102. function(_add_lapack_target)
  103. if(LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK)
  104. add_library(LAPACK::LAPACK INTERFACE IMPORTED)
  105. # Filter out redundant BLAS info and replace with the BLAS target
  106. set(_lapack_libs "${LAPACK_LIBRARIES}")
  107. set(_lapack_flags "${LAPACK_LINKER_FLAGS}")
  108. if(TARGET BLAS::BLAS)
  109. if(_lapack_libs AND BLAS_LIBRARIES)
  110. foreach(_blas_lib IN LISTS BLAS_LIBRARIES)
  111. list(REMOVE_ITEM _lapack_libs "${_blas_lib}")
  112. endforeach()
  113. endif()
  114. if(_lapack_flags AND BLAS_LINKER_FLAGS)
  115. foreach(_blas_flag IN LISTS BLAS_LINKER_FLAGS)
  116. list(REMOVE_ITEM _lapack_flags "${_blas_flag}")
  117. endforeach()
  118. endif()
  119. list(APPEND _lapack_libs BLAS::BLAS)
  120. endif()
  121. if(_lapack_libs)
  122. set_target_properties(LAPACK::LAPACK PROPERTIES
  123. INTERFACE_LINK_LIBRARIES "${_lapack_libs}"
  124. )
  125. endif()
  126. if(_lapack_flags)
  127. set_target_properties(LAPACK::LAPACK PROPERTIES
  128. INTERFACE_LINK_OPTIONS "${_lapack_flags}"
  129. )
  130. endif()
  131. endif()
  132. endfunction()
  133. # TODO: move this stuff to a separate module
  134. function(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _deps _addlibdir _subdirs _blas)
  135. # This function checks for the existence of the combination of libraries
  136. # given by _list. If the combination is found, this checks whether can link
  137. # against that library combination using the name of a routine given by _name
  138. # using the linker flags given by _flags. If the combination of libraries is
  139. # found and passes the link test, ${LIBRARIES} is set to the list of complete
  140. # library paths that have been found. Otherwise, ${LIBRARIES} is set to FALSE.
  141. set(_libraries_work TRUE)
  142. set(_libraries)
  143. set(_combined_name)
  144. if(BLA_STATIC)
  145. if(WIN32)
  146. set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
  147. else()
  148. set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
  149. endif()
  150. else()
  151. if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  152. # for ubuntu's libblas3gf and liblapack3gf packages
  153. set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
  154. endif()
  155. endif()
  156. set(_extaddlibdir "${_addlibdir}")
  157. if(WIN32)
  158. list(APPEND _extaddlibdir ENV LIB)
  159. elseif(APPLE)
  160. list(APPEND _extaddlibdir ENV DYLD_LIBRARY_PATH)
  161. else()
  162. list(APPEND _extaddlibdir ENV LD_LIBRARY_PATH)
  163. endif()
  164. list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
  165. foreach(_library ${_list})
  166. if(_library MATCHES "^-")
  167. # Respect linker flags as-is (required by MKL)
  168. list(APPEND _libraries "${_library}")
  169. else()
  170. string(REGEX REPLACE "[^A-Za-z0-9]" "_" _lib_var "${_library}")
  171. string(APPEND _combined_name "_${_lib_var}")
  172. if(NOT "${_deps}" STREQUAL "")
  173. string(APPEND _combined_name "_deps")
  174. endif()
  175. if(_libraries_work)
  176. find_library(${_prefix}_${_lib_var}_LIBRARY
  177. NAMES ${_library}
  178. NAMES_PER_DIR
  179. PATHS ${_extaddlibdir}
  180. PATH_SUFFIXES ${_subdirs}
  181. )
  182. mark_as_advanced(${_prefix}_${_lib_var}_LIBRARY)
  183. list(APPEND _libraries ${${_prefix}_${_lib_var}_LIBRARY})
  184. set(_libraries_work ${${_prefix}_${_lib_var}_LIBRARY})
  185. endif()
  186. endif()
  187. endforeach()
  188. foreach(_flag ${_flags})
  189. string(REGEX REPLACE "[^A-Za-z0-9]" "_" _flag_var "${_flag}")
  190. string(APPEND _combined_name "_${_flag_var}")
  191. endforeach()
  192. if(_libraries_work)
  193. # Test this combination of libraries.
  194. set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${_libraries} ${_blas} ${_deps})
  195. set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY})
  196. if(CMAKE_Fortran_COMPILER_LOADED)
  197. check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
  198. else()
  199. check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
  200. endif()
  201. set(CMAKE_REQUIRED_LIBRARIES)
  202. set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
  203. endif()
  204. if(_libraries_work)
  205. if("${_list}${_blas}" STREQUAL "")
  206. set(_libraries "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
  207. else()
  208. list(APPEND _libraries ${_blas} ${_deps})
  209. endif()
  210. else()
  211. set(_libraries FALSE)
  212. endif()
  213. set(${LIBRARIES} "${_libraries}" PARENT_SCOPE)
  214. endfunction()
  215. macro(_lapack_find_dependency dep)
  216. set(_lapack_quiet_arg)
  217. if(LAPACK_FIND_QUIETLY)
  218. set(_lapack_quiet_arg QUIET)
  219. endif()
  220. set(_lapack_required_arg)
  221. if(LAPACK_FIND_REQUIRED)
  222. set(_lapack_required_arg REQUIRED)
  223. endif()
  224. find_package(${dep} ${ARGN}
  225. ${_lapack_quiet_arg}
  226. ${_lapack_required_arg}
  227. )
  228. if (NOT ${dep}_FOUND)
  229. set(LAPACK_NOT_FOUND_MESSAGE "LAPACK could not be found because dependency ${dep} could not be found.")
  230. endif()
  231. set(_lapack_required_arg)
  232. set(_lapack_quiet_arg)
  233. endmacro()
  234. set(LAPACK_LINKER_FLAGS)
  235. set(LAPACK_LIBRARIES)
  236. set(LAPACK95_LIBRARIES)
  237. set(_lapack_fphsa_req_var LAPACK_LIBRARIES)
  238. # Check the language being used
  239. if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
  240. set(LAPACK_NOT_FOUND_MESSAGE
  241. "FindLAPACK requires Fortran, C, or C++ to be enabled.")
  242. endif()
  243. if(NOT BLA_SIZEOF_INTEGER)
  244. # in the reality we do not know which API of BLAS/LAPACK is masked in library
  245. set(_lapack_sizeof_integer "ANY")
  246. elseif((BLA_SIZEOF_INTEGER STREQUAL "ANY") OR
  247. (BLA_SIZEOF_INTEGER STREQUAL "4") OR
  248. (BLA_SIZEOF_INTEGER STREQUAL "8"))
  249. set(_lapack_sizeof_integer ${BLA_SIZEOF_INTEGER})
  250. else()
  251. message(FATAL_ERROR "BLA_SIZEOF_INTEGER can have only <no value>, ANY, 4, or 8 values")
  252. endif()
  253. if(NOT BLA_THREAD)
  254. set(_lapack_thread "ANY")
  255. elseif((BLA_THREAD STREQUAL "ANY") OR
  256. (BLA_THREAD STREQUAL "SEQ") OR
  257. (BLA_THREAD STREQUAL "OMP"))
  258. set(_lapack_thread ${BLA_THREAD})
  259. else()
  260. message(FATAL_ERROR "BLA_THREAD can have only <no value>, ANY, SEQ, or OMP values")
  261. endif()
  262. # Load BLAS
  263. if(NOT LAPACK_NOT_FOUND_MESSAGE)
  264. _lapack_find_dependency(BLAS)
  265. endif()
  266. # Search with pkg-config if specified
  267. if(BLA_PREFER_PKGCONFIG)
  268. if(NOT BLA_PKGCONFIG_LAPACK)
  269. set(BLA_PKGCONFIG_LAPACK "lapack")
  270. endif()
  271. find_package(PkgConfig QUIET)
  272. if(PkgConfig_FOUND)
  273. pkg_check_modules(PKGC_LAPACK QUIET ${BLA_PKGCONFIG_LAPACK})
  274. if(PKGC_LAPACK_FOUND)
  275. set(LAPACK_FOUND TRUE)
  276. set(LAPACK_LIBRARIES "${PKGC_LAPACK_LINK_LIBRARIES}")
  277. if (BLAS_LIBRARIES)
  278. list(APPEND LAPACK_LIBRARIES "${BLAS_LIBRARIES}")
  279. endif()
  280. _add_lapack_target()
  281. return()
  282. endif()
  283. endif()
  284. endif()
  285. # Search for different LAPACK distributions if BLAS is found
  286. if(NOT LAPACK_NOT_FOUND_MESSAGE)
  287. set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
  288. if(NOT BLA_VENDOR)
  289. if(NOT "$ENV{BLA_VENDOR}" STREQUAL "")
  290. set(BLA_VENDOR "$ENV{BLA_VENDOR}")
  291. else()
  292. set(BLA_VENDOR "All")
  293. endif()
  294. endif()
  295. # LAPACK in the Intel MKL 10+ library?
  296. if(NOT LAPACK_LIBRARIES
  297. AND (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
  298. AND (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED))
  299. # System-specific settings
  300. if(NOT WIN32)
  301. set(LAPACK_mkl_LM "-lm")
  302. set(LAPACK_mkl_LDL "-ldl")
  303. endif()
  304. _lapack_find_dependency(Threads)
  305. if(_lapack_sizeof_integer EQUAL 8)
  306. set(LAPACK_mkl_ILP_MODE "ilp64")
  307. elseif(_lapack_sizeof_integer EQUAL 4)
  308. set(LAPACK_mkl_ILP_MODE "lp64")
  309. else()
  310. if(BLA_VENDOR MATCHES "_64ilp")
  311. set(LAPACK_mkl_ILP_MODE "ilp64")
  312. else()
  313. set(LAPACK_mkl_ILP_MODE "lp64")
  314. endif()
  315. endif()
  316. set(LAPACK_SEARCH_LIBS "")
  317. if(BLA_F95)
  318. set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95")
  319. set(_LAPACK_LIBRARIES LAPACK95_LIBRARIES)
  320. set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
  321. # old
  322. list(APPEND LAPACK_SEARCH_LIBS
  323. "mkl_lapack95")
  324. # new >= 10.3
  325. list(APPEND LAPACK_SEARCH_LIBS
  326. "mkl_intel_c")
  327. list(APPEND LAPACK_SEARCH_LIBS
  328. "mkl_lapack95_${LAPACK_mkl_ILP_MODE}")
  329. else()
  330. set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
  331. set(_LAPACK_LIBRARIES LAPACK_LIBRARIES)
  332. set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
  333. # old and new >= 10.3
  334. list(APPEND LAPACK_SEARCH_LIBS
  335. "mkl_lapack")
  336. endif()
  337. # MKL uses a multitude of partially platform-specific subdirectories:
  338. if(BLA_VENDOR STREQUAL "Intel10_32")
  339. set(LAPACK_mkl_ARCH_NAME "ia32")
  340. else()
  341. set(LAPACK_mkl_ARCH_NAME "intel64")
  342. endif()
  343. if(WIN32)
  344. set(LAPACK_mkl_OS_NAME "win")
  345. elseif(APPLE)
  346. set(LAPACK_mkl_OS_NAME "mac")
  347. else()
  348. set(LAPACK_mkl_OS_NAME "lin")
  349. endif()
  350. if(DEFINED ENV{MKLROOT})
  351. file(TO_CMAKE_PATH "$ENV{MKLROOT}" LAPACK_mkl_MKLROOT)
  352. # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
  353. # so we can better detect other relevant libraries in 'compiler' or 'tbb':
  354. get_filename_component(LAPACK_mkl_MKLROOT_LAST_DIR "${LAPACK_mkl_MKLROOT}" NAME)
  355. if(LAPACK_mkl_MKLROOT_LAST_DIR STREQUAL "mkl")
  356. get_filename_component(LAPACK_mkl_MKLROOT "${LAPACK_mkl_MKLROOT}" DIRECTORY)
  357. endif()
  358. endif()
  359. set(LAPACK_mkl_LIB_PATH_SUFFIXES
  360. "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
  361. "compiler/lib/${LAPACK_mkl_ARCH_NAME}"
  362. "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
  363. "mkl/lib/${LAPACK_mkl_ARCH_NAME}"
  364. "lib" "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
  365. "lib/${LAPACK_mkl_ARCH_NAME}"
  366. )
  367. # First try empty lapack libs (implicitly linked or automatic from BLAS)
  368. if(NOT ${_LAPACK_LIBRARIES})
  369. check_lapack_libraries(
  370. ${_LAPACK_LIBRARIES}
  371. LAPACK
  372. ${LAPACK_mkl_SEARCH_SYMBOL}
  373. ""
  374. ""
  375. "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
  376. "${LAPACK_mkl_MKLROOT}"
  377. "${LAPACK_mkl_LIB_PATH_SUFFIXES}"
  378. "${_BLAS_LIBRARIES}"
  379. )
  380. if(LAPACK_WORKS AND NOT _BLAS_LIBRARIES)
  381. # Give a more helpful "found" message
  382. set(LAPACK_WORKS "implicitly linked")
  383. set(_lapack_fphsa_req_var LAPACK_WORKS)
  384. endif()
  385. endif()
  386. # Then try the search libs
  387. foreach(_search ${LAPACK_SEARCH_LIBS})
  388. string(REPLACE " " ";" _search ${_search})
  389. if(NOT ${_LAPACK_LIBRARIES})
  390. check_lapack_libraries(
  391. ${_LAPACK_LIBRARIES}
  392. LAPACK
  393. ${LAPACK_mkl_SEARCH_SYMBOL}
  394. ""
  395. "${_search}"
  396. "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
  397. "${LAPACK_mkl_MKLROOT}"
  398. "${LAPACK_mkl_LIB_PATH_SUFFIXES}"
  399. "${_BLAS_LIBRARIES}"
  400. )
  401. endif()
  402. endforeach()
  403. unset(_search)
  404. unset(LAPACK_mkl_ILP_MODE)
  405. unset(LAPACK_mkl_SEARCH_SYMBOL)
  406. unset(LAPACK_mkl_LM)
  407. unset(LAPACK_mkl_LDL)
  408. unset(LAPACK_mkl_MKLROOT)
  409. unset(LAPACK_mkl_ARCH_NAME)
  410. unset(LAPACK_mkl_OS_NAME)
  411. unset(LAPACK_mkl_LIB_PATH_SUFFIXES)
  412. endif()
  413. # gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
  414. if(NOT LAPACK_LIBRARIES
  415. AND (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All"))
  416. check_lapack_libraries(
  417. LAPACK_LIBRARIES
  418. LAPACK
  419. cheev
  420. ""
  421. "goto2"
  422. ""
  423. ""
  424. ""
  425. "${BLAS_LIBRARIES}"
  426. )
  427. endif()
  428. # FlexiBLAS? (http://www.mpi-magdeburg.mpg.de/mpcsc/software/FlexiBLAS/)
  429. if(NOT LAPACK_LIBRARIES
  430. AND (BLA_VENDOR STREQUAL "FlexiBLAS" OR BLA_VENDOR STREQUAL "All"))
  431. set(_lapack_flexiblas_lib "flexiblas")
  432. if(_lapack_sizeof_integer EQUAL 8)
  433. string(APPEND _lapack_flexiblas_lib "64")
  434. endif()
  435. check_lapack_libraries(
  436. LAPACK_LIBRARIES
  437. LAPACK
  438. cheev
  439. ""
  440. "${_lapack_flexiblas_lib}"
  441. ""
  442. ""
  443. ""
  444. "${BLAS_LIBRARIES}"
  445. )
  446. unset(_lapack_flexiblas_lib)
  447. endif()
  448. # OpenBLAS? (http://www.openblas.net)
  449. if(NOT LAPACK_LIBRARIES
  450. AND (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All"))
  451. set(_lapack_openblas_lib "openblas")
  452. if(_lapack_sizeof_integer EQUAL 8)
  453. if(MINGW)
  454. string(APPEND _lapack_openblas_lib "_64")
  455. else()
  456. string(APPEND _lapack_openblas_lib "64")
  457. endif()
  458. endif()
  459. check_lapack_libraries(
  460. LAPACK_LIBRARIES
  461. LAPACK
  462. cheev
  463. ""
  464. "${_lapack_openblas_lib}"
  465. ""
  466. ""
  467. ""
  468. "${BLAS_LIBRARIES}"
  469. )
  470. unset(_lapack_openblas_lib)
  471. endif()
  472. # ArmPL? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
  473. if(NOT LAPACK_LIBRARIES
  474. AND (BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All"))
  475. # Check for 64bit Integer support
  476. if(_lapack_sizeof_integer EQUAL 8)
  477. set(LAPACK_armpl_LIB "armpl_ilp64")
  478. elseif(_lapack_sizeof_integer EQUAL 4)
  479. set(LAPACK_armpl_LIB "armpl_lp64")
  480. else()
  481. if(BLA_VENDOR MATCHES "_ilp64")
  482. set(LAPACK_armpl_LIB "armpl_ilp64")
  483. else()
  484. set(LAPACK_armpl_LIB "armpl_lp64")
  485. endif()
  486. endif()
  487. # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
  488. if(BLA_VENDOR MATCHES "_mp")
  489. string(APPEND LAPACK_armpl_LIB "_mp")
  490. endif()
  491. check_lapack_libraries(
  492. LAPACK_LIBRARIES
  493. LAPACK
  494. cheev
  495. ""
  496. "${LAPACK_armpl_LIB}"
  497. ""
  498. ""
  499. ""
  500. "${BLAS_LIBRARIES}"
  501. )
  502. endif()
  503. # FLAME's blis library? (https://github.com/flame/blis)
  504. if(NOT LAPACK_LIBRARIES
  505. AND (BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All"))
  506. if(_lapack_sizeof_integer EQUAL 8)
  507. if(BLA_VENDOR STREQUAL "FLAME")
  508. message(FATAL_ERROR "libFLAME does not support Int64 type")
  509. endif()
  510. else()
  511. check_lapack_libraries(
  512. LAPACK_LIBRARIES
  513. LAPACK
  514. cheev
  515. ""
  516. "flame"
  517. ""
  518. ""
  519. ""
  520. "${BLAS_LIBRARIES}"
  521. )
  522. endif()
  523. endif()
  524. # AOCL? (https://developer.amd.com/amd-aocl/)
  525. if(NOT LAPACK_LIBRARIES
  526. AND (BLA_VENDOR MATCHES "AOCL" OR BLA_VENDOR STREQUAL "All"))
  527. if(_lapack_sizeof_integer EQUAL 8)
  528. set(_lapack_aocl_subdir "ILP64")
  529. else()
  530. set(_lapack_aocl_subdir "LP64")
  531. endif()
  532. check_lapack_libraries(
  533. LAPACK_LIBRARIES
  534. LAPACK
  535. cheev
  536. ""
  537. "flame"
  538. "-fopenmp"
  539. ""
  540. "${_lapack_aocl_subdir}"
  541. "${BLAS_LIBRARIES}"
  542. )
  543. unset(_lapack_aocl_subdir)
  544. endif()
  545. # LAPACK in SCSL library? (SGI/Cray Scientific Library)
  546. if(NOT LAPACK_LIBRARIES
  547. AND (BLA_VENDOR MATCHES "SCSL" OR BLA_VENDOR STREQUAL "All"))
  548. set(_lapack_scsl_lib "scs")
  549. if(_lapack_sizeof_integer EQUAL 8)
  550. string(APPEND _lapack_scsl_lib "_i8")
  551. endif()
  552. # Check for OpenMP support, VIA BLA_VENDOR of scs_mp
  553. if(BLA_VENDOR MATCHES "_mp")
  554. string(APPEND _lapack_scsl_lib "_mp")
  555. endif()
  556. check_lapack_libraries(
  557. LAPACK_LIBRARIES
  558. LAPACK
  559. cheev
  560. ""
  561. "${_lapack_scsl_lib}"
  562. ""
  563. ""
  564. ""
  565. "${BLAS_LIBRARIES}"
  566. )
  567. unset(_lapack_scsl_lib)
  568. endif()
  569. # BLAS in acml library?
  570. if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
  571. if(BLAS_LIBRARIES MATCHES ".+acml.+")
  572. set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
  573. endif()
  574. endif()
  575. # Apple LAPACK library?
  576. if(NOT LAPACK_LIBRARIES
  577. AND (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All"))
  578. if(_lapack_sizeof_integer EQUAL 8)
  579. if(BLA_VENDOR STREQUAL "Apple")
  580. message(FATAL_ERROR "Accelerate Framework does not support Int64 type")
  581. endif()
  582. else()
  583. check_lapack_libraries(
  584. LAPACK_LIBRARIES
  585. LAPACK
  586. cheev
  587. ""
  588. "Accelerate"
  589. ""
  590. ""
  591. ""
  592. "${BLAS_LIBRARIES}"
  593. )
  594. endif()
  595. endif()
  596. # Apple NAS (vecLib) library?
  597. if(NOT LAPACK_LIBRARIES
  598. AND (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All"))
  599. if(_lapack_sizeof_integer EQUAL 8)
  600. if(BLA_VENDOR STREQUAL "NAS")
  601. message(FATAL_ERROR "Accelerate Framework does not support Int64 type")
  602. endif()
  603. else()
  604. check_lapack_libraries(
  605. LAPACK_LIBRARIES
  606. LAPACK
  607. cheev
  608. ""
  609. "vecLib"
  610. ""
  611. ""
  612. ""
  613. "${BLAS_LIBRARIES}"
  614. )
  615. endif()
  616. endif()
  617. # Elbrus Math Library?
  618. if(NOT LAPACK_LIBRARIES
  619. AND (BLA_VENDOR MATCHES "EML" OR BLA_VENDOR STREQUAL "All"))
  620. if(BLAS_LIBRARIES MATCHES "eml.+")
  621. set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
  622. endif()
  623. endif()
  624. # Fujitsu SSL2 Library?
  625. if(NOT LAPACK_LIBRARIES
  626. AND (BLA_VENDOR MATCHES "Fujitsu_SSL2" OR BLA_VENDOR STREQUAL "All"))
  627. if(BLAS_LIBRARIES MATCHES "fjlapack.+")
  628. set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
  629. set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
  630. endif()
  631. endif()
  632. # LAPACK in IBM ESSL library?
  633. if(NOT LAPACK_LIBRARIES
  634. AND (BLA_VENDOR MATCHES "IBMESSL" OR BLA_VENDOR STREQUAL "All"))
  635. if(BLAS_LIBRARIES MATCHES "essl.+")
  636. set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
  637. endif()
  638. endif()
  639. # nVidia NVPL? (https://developer.nvidia.com/nvpl)
  640. if(NOT LAPACK_LIBRARIES
  641. AND (BLA_VENDOR MATCHES "NVPL" OR BLA_VENDOR STREQUAL "All"))
  642. # Prefer lp64 unless ilp64 is requested.
  643. if((_lapack_sizeof_integer EQUAL 4) OR (_lapack_sizeof_integer STREQUAL "ANY"))
  644. list(APPEND _lapack_nvpl_ints "_lp64")
  645. endif()
  646. if((_lapack_sizeof_integer EQUAL 8) OR (_lapack_sizeof_integer STREQUAL "ANY"))
  647. list(APPEND _lapack_nvpl_ints "_ilp64")
  648. endif()
  649. # Prefer OMP if available
  650. if((_lapack_thread STREQUAL "OMP") OR (_lapack_thread STREQUAL "ANY"))
  651. list(APPEND _lapack_nvpl_threads "_omp")
  652. endif()
  653. if((_lapack_thread STREQUAL "SEQ") OR (_lapack_thread STREQUAL "ANY"))
  654. list(APPEND _lapack_nvpl_threads "_seq")
  655. endif()
  656. find_package(nvpl)
  657. if(nvpl_FOUND)
  658. foreach(_nvpl_thread IN LISTS _lapack_nvpl_threads)
  659. foreach(_nvpl_int IN LISTS _lapack_nvpl_ints)
  660. set(_lapack_lib "nvpl::lapack${_nvpl_int}${_nvpl_thread}")
  661. if(TARGET ${_lapack_lib})
  662. set(LAPACK_LIBRARIES ${_lapack_lib})
  663. break()
  664. endif()
  665. endforeach()
  666. if(LAPACK_LIBRARIES)
  667. break()
  668. endif()
  669. endforeach()
  670. endif()
  671. unset(_lapack_lib)
  672. unset(_lapack_nvpl_ints)
  673. unset(_lapack_nvpl_threads)
  674. endif()
  675. # NVHPC Library?
  676. if(NOT LAPACK_LIBRARIES
  677. AND (BLA_VENDOR MATCHES "NVHPC" OR BLA_VENDOR STREQUAL "All"))
  678. set(_lapack_nvhpc_lib "lapack")
  679. if(_lapack_sizeof_integer EQUAL 8)
  680. string(APPEND _lapack_nvhpc_lib "_ilp64")
  681. elseif(_lapack_sizeof_integer EQUAL 4)
  682. string(APPEND _lapack_nvhpc_lib "_lp64")
  683. endif()
  684. set(_lapack_nvhpc_flags)
  685. if(";${CMAKE_C_COMPILER_ID};${CMAKE_CXX_COMPILER_ID};${CMAKE_Fortran_COMPILER_ID};" MATCHES ";(NVHPC|PGI);")
  686. set(_lapack_nvhpc_flags "-fortranlibs")
  687. endif()
  688. check_lapack_libraries(
  689. LAPACK_LIBRARIES
  690. LAPACK
  691. cheev
  692. ""
  693. "${_lapack_nvhpc_lib}"
  694. "${_lapack_nvhpc_flags}"
  695. ""
  696. ""
  697. "${BLAS_LIBRARIES}"
  698. )
  699. # an additional check for NVHPC 2020
  700. # which does not have differentiation
  701. # between lp64 and ilp64 modes
  702. if(NOT LAPACK_LIBRARIES AND NOT _lapack_sizeof_integer EQUAL 8)
  703. set(_lapack_nvhpc_lib "lapack")
  704. check_lapack_libraries(
  705. LAPACK_LIBRARIES
  706. LAPACK
  707. cheev
  708. ""
  709. "${_lapack_nvhpc_lib}"
  710. "${_lapack_nvhpc_flags}"
  711. ""
  712. ""
  713. "${BLAS_LIBRARIES}"
  714. )
  715. endif()
  716. unset(_lapack_nvhpc_lib)
  717. unset(_lapack_nvhpc_flags)
  718. endif()
  719. # libblastrampoline? (https://github.com/JuliaLinearAlgebra/libblastrampoline/tree/main)
  720. if(NOT LAPACK_LIBRARIES
  721. AND (BLA_VENDOR STREQUAL "libblastrampoline" OR BLA_VENDOR STREQUAL "All"))
  722. if(BLAS_LIBRARIES MATCHES "blastrampoline.+")
  723. set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
  724. endif()
  725. endif()
  726. # Generic LAPACK library?
  727. if(NOT LAPACK_LIBRARIES
  728. AND (BLA_VENDOR STREQUAL "Generic"
  729. OR BLA_VENDOR STREQUAL "ATLAS"
  730. OR BLA_VENDOR STREQUAL "All"))
  731. set(_lapack_generic_lib "lapack")
  732. if(BLA_STATIC)
  733. # We do not know for sure how the LAPACK reference implementation
  734. # is built on this host. Guess typical dependencies.
  735. set(_lapack_generic_deps "-lgfortran;-lm")
  736. else()
  737. set(_lapack_generic_deps "")
  738. endif()
  739. if(_lapack_sizeof_integer EQUAL 8)
  740. string(APPEND _lapack_generic_lib "64")
  741. endif()
  742. check_lapack_libraries(
  743. LAPACK_LIBRARIES
  744. LAPACK
  745. cheev
  746. ""
  747. "${_lapack_generic_lib}"
  748. "${_lapack_generic_deps}"
  749. ""
  750. ""
  751. "${BLAS_LIBRARIES}"
  752. )
  753. unset(_lapack_generic_deps)
  754. unset(_lapack_generic_lib)
  755. endif()
  756. endif()
  757. if(BLA_F95)
  758. set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}")
  759. endif()
  760. if(LAPACK_NOT_FOUND_MESSAGE)
  761. set(LAPACK_NOT_FOUND_MESSAGE
  762. REASON_FAILURE_MESSAGE ${LAPACK_NOT_FOUND_MESSAGE})
  763. endif()
  764. find_package_handle_standard_args(LAPACK REQUIRED_VARS ${_lapack_fphsa_req_var}
  765. ${LAPACK_NOT_FOUND_MESSAGE})
  766. unset(LAPACK_NOT_FOUND_MESSAGE)
  767. if(BLA_F95)
  768. set(LAPACK95_FOUND ${LAPACK_FOUND})
  769. endif()
  770. # On compilers that implicitly link LAPACK (such as ftn, cc, and CC on Cray HPC machines)
  771. # we used a placeholder for empty LAPACK_LIBRARIES to get through our logic above.
  772. if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
  773. set(LAPACK_LIBRARIES "")
  774. endif()
  775. _add_lapack_target()
  776. unset(_lapack_fphsa_req_var)
  777. unset(_lapack_sizeof_integer)
  778. unset(_LAPACK_LIBRARIES)