FindBLAS.cmake 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. FindBLAS
  5. --------
  6. Find Basic Linear Algebra Subprograms (BLAS) library
  7. This module finds an installed Fortran library that implements the
  8. BLAS linear-algebra interface (see http://www.netlib.org/blas/).
  9. The approach follows that taken for the ``autoconf`` macro file,
  10. ``acx_blas.m4`` (distributed at
  11. http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
  12. Input Variables
  13. ^^^^^^^^^^^^^^^
  14. The following variables may be set to influence this module's behavior:
  15. ``BLA_STATIC``
  16. if ``ON`` use static linkage
  17. ``BLA_VENDOR``
  18. If set, checks only the specified vendor, if not set checks all the
  19. possibilities. List of vendors valid in this module:
  20. * ``Goto``
  21. * ``OpenBLAS``
  22. * ``FLAME``
  23. * ``ATLAS PhiPACK``
  24. * ``CXML``
  25. * ``DXML``
  26. * ``SunPerf``
  27. * ``SCSL``
  28. * ``SGIMATH``
  29. * ``IBMESSL``
  30. * ``Intel10_32`` (intel mkl v10 32 bit, threaded code)
  31. * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
  32. * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
  33. * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
  34. * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model)
  35. * ``Intel10_64_dyn`` (intel mkl v10+ 64 bit, single dynamic library)
  36. * ``Intel`` (obsolete versions of mkl 32 and 64 bit)
  37. * ``ACML``
  38. * ``ACML_MP``
  39. * ``ACML_GPU``
  40. * ``Apple``
  41. * ``NAS``
  42. * ``Arm``
  43. * ``Arm_mp``
  44. * ``Arm_ilp64``
  45. * ``Arm_ilp64_mp``
  46. * ``Generic``
  47. ``BLA_F95``
  48. if ``ON`` tries to find the BLAS95 interfaces
  49. ``BLA_PREFER_PKGCONFIG``
  50. if set ``pkg-config`` will be used to search for a BLAS library first
  51. and if one is found that is preferred
  52. Imported targets
  53. ^^^^^^^^^^^^^^^^
  54. This module defines the following :prop_tgt:`IMPORTED` target:
  55. ``BLAS::BLAS``
  56. The libraries to use for BLAS, if found.
  57. Result Variables
  58. ^^^^^^^^^^^^^^^^
  59. This module defines the following variables:
  60. ``BLAS_FOUND``
  61. library implementing the BLAS interface is found
  62. ``BLAS_LINKER_FLAGS``
  63. uncached list of required linker flags (excluding ``-l`` and ``-L``).
  64. ``BLAS_LIBRARIES``
  65. uncached list of libraries (using full path name) to link against
  66. to use BLAS (may be empty if compiler implicitly links BLAS)
  67. ``BLAS95_LIBRARIES``
  68. uncached list of libraries (using full path name) to link against
  69. to use BLAS95 interface
  70. ``BLAS95_FOUND``
  71. library implementing the BLAS95 interface is found
  72. .. note::
  73. C, CXX or Fortran must be enabled to detect a BLAS library.
  74. C or CXX must be enabled to use Intel Math Kernel Library (MKL).
  75. For example, to use Intel MKL libraries and/or Intel compiler:
  76. .. code-block:: cmake
  77. set(BLA_VENDOR Intel10_64lp)
  78. find_package(BLAS)
  79. Hints
  80. ^^^^^
  81. Set the ``MKLROOT`` environment variable to a directory that contains an MKL
  82. installation, or add the directory to the dynamic library loader environment
  83. variable for your platform (``LIB``, ``DYLD_LIBRARY_PATH`` or
  84. ``LD_LIBRARY_PATH``).
  85. #]=======================================================================]
  86. # Check the language being used
  87. if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
  88. if(BLAS_FIND_REQUIRED)
  89. message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
  90. else()
  91. message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)")
  92. return()
  93. endif()
  94. endif()
  95. function(_add_blas_target)
  96. if(NOT TARGET BLAS::BLAS)
  97. add_library(BLAS::BLAS INTERFACE IMPORTED)
  98. if(BLAS_LIBRARIES)
  99. set_target_properties(BLAS::BLAS PROPERTIES
  100. INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}"
  101. )
  102. endif()
  103. endif()
  104. endfunction()
  105. if(CMAKE_Fortran_COMPILER_LOADED)
  106. include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
  107. else()
  108. include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
  109. endif()
  110. include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
  111. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  112. cmake_push_check_state()
  113. set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY})
  114. if(BLA_PREFER_PKGCONFIG)
  115. find_package(PkgConfig)
  116. pkg_check_modules(PKGC_BLAS blas)
  117. if(PKGC_BLAS_FOUND)
  118. set(BLAS_FOUND ${PKGC_BLAS_FOUND})
  119. set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}")
  120. _add_blas_target()
  121. return()
  122. endif()
  123. endif()
  124. set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
  125. if(BLA_STATIC)
  126. if(WIN32)
  127. set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
  128. else()
  129. set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
  130. endif()
  131. else()
  132. if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  133. # for ubuntu's libblas3gf and liblapack3gf packages
  134. set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
  135. endif()
  136. endif()
  137. # TODO: move this stuff to a separate module
  138. macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs)
  139. # This macro checks for the existence of the combination of fortran libraries
  140. # given by _list. If the combination is found, this macro checks (using the
  141. # Check_Fortran_Function_Exists macro) whether can link against that library
  142. # combination using the name of a routine given by _name using the linker
  143. # flags given by _flags. If the combination of libraries is found and passes
  144. # the link test, LIBRARIES is set to the list of complete library paths that
  145. # have been found. Otherwise, LIBRARIES is set to FALSE.
  146. # N.B. _prefix is the prefix applied to the names of all cached variables that
  147. # are generated internally and marked advanced by this macro.
  148. # _addlibdir is a list of additional search paths. _subdirs is a list of path
  149. # suffixes to be used by find_library().
  150. set(_libraries_work TRUE)
  151. set(${LIBRARIES})
  152. set(_combined_name)
  153. set(_extaddlibdir "${_addlibdir}")
  154. if(WIN32)
  155. list(APPEND _extaddlibdir ENV LIB)
  156. elseif(APPLE)
  157. list(APPEND _extaddlibdir ENV DYLD_LIBRARY_PATH)
  158. else()
  159. list(APPEND _extaddlibdir ENV LD_LIBRARY_PATH)
  160. endif()
  161. list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
  162. foreach(_library ${_list})
  163. if(_library MATCHES "^-Wl,--(start|end)-group$")
  164. # Respect linker flags like --start/end-group (required by MKL)
  165. set(${LIBRARIES} ${${LIBRARIES}} "${_library}")
  166. else()
  167. set(_combined_name ${_combined_name}_${_library})
  168. if(NOT "${_threadlibs}" STREQUAL "")
  169. set(_combined_name ${_combined_name}_threadlibs)
  170. endif()
  171. if(_libraries_work)
  172. find_library(${_prefix}_${_library}_LIBRARY
  173. NAMES ${_library}
  174. PATHS ${_extaddlibdir}
  175. PATH_SUFFIXES ${_subdirs}
  176. )
  177. #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}")
  178. mark_as_advanced(${_prefix}_${_library}_LIBRARY)
  179. set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
  180. set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
  181. endif()
  182. endif()
  183. endforeach()
  184. if(_libraries_work)
  185. # Test this combination of libraries.
  186. set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threadlibs})
  187. #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
  188. if(CMAKE_Fortran_COMPILER_LOADED)
  189. check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
  190. else()
  191. check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
  192. endif()
  193. set(CMAKE_REQUIRED_LIBRARIES)
  194. set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
  195. endif()
  196. if(_libraries_work)
  197. if("${_list}" STREQUAL "")
  198. set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
  199. else()
  200. set(${LIBRARIES} ${${LIBRARIES}} ${_threadlibs})
  201. endif()
  202. else()
  203. set(${LIBRARIES} FALSE)
  204. endif()
  205. #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
  206. endmacro()
  207. set(BLAS_LINKER_FLAGS)
  208. set(BLAS_LIBRARIES)
  209. set(BLAS95_LIBRARIES)
  210. if(NOT $ENV{BLA_VENDOR} STREQUAL "")
  211. set(BLA_VENDOR $ENV{BLA_VENDOR})
  212. else()
  213. if(NOT BLA_VENDOR)
  214. set(BLA_VENDOR "All")
  215. endif()
  216. endif()
  217. # Implicitly linked BLAS libraries?
  218. if(BLA_VENDOR STREQUAL "All")
  219. if(NOT BLAS_LIBRARIES)
  220. check_blas_libraries(
  221. BLAS_LIBRARIES
  222. BLAS
  223. sgemm
  224. ""
  225. ""
  226. ""
  227. ""
  228. ""
  229. )
  230. endif()
  231. endif()
  232. # BLAS in the Intel MKL 10+ library?
  233. if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
  234. if(NOT BLAS_LIBRARIES)
  235. if(CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
  236. # System-specific settings
  237. if(WIN32)
  238. if(BLA_STATIC)
  239. set(BLAS_mkl_DLL_SUFFIX "")
  240. else()
  241. set(BLAS_mkl_DLL_SUFFIX "_dll")
  242. endif()
  243. else()
  244. if(BLA_STATIC)
  245. set(BLAS_mkl_START_GROUP "-Wl,--start-group")
  246. set(BLAS_mkl_END_GROUP "-Wl,--end-group")
  247. else()
  248. set(BLAS_mkl_START_GROUP "")
  249. set(BLAS_mkl_END_GROUP "")
  250. endif()
  251. # Switch to GNU Fortran support layer if needed (but not on Apple, where MKL does not provide it)
  252. if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE)
  253. set(BLAS_mkl_INTFACE "gf")
  254. set(BLAS_mkl_THREADING "gnu")
  255. set(BLAS_mkl_OMP "gomp")
  256. else()
  257. set(BLAS_mkl_INTFACE "intel")
  258. set(BLAS_mkl_THREADING "intel")
  259. set(BLAS_mkl_OMP "iomp5")
  260. endif()
  261. set(BLAS_mkl_LM "-lm")
  262. set(BLAS_mkl_LDL "-ldl")
  263. endif()
  264. if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
  265. find_package(Threads)
  266. else()
  267. find_package(Threads REQUIRED)
  268. endif()
  269. if(BLA_VENDOR MATCHES "_64ilp")
  270. set(BLAS_mkl_ILP_MODE "ilp64")
  271. else()
  272. set(BLAS_mkl_ILP_MODE "lp64")
  273. endif()
  274. set(BLAS_SEARCH_LIBS "")
  275. if(BLA_F95)
  276. set(BLAS_mkl_SEARCH_SYMBOL "sgemm_f95")
  277. set(_LIBRARIES BLAS95_LIBRARIES)
  278. if(WIN32)
  279. # Find the main file (32-bit or 64-bit)
  280. set(BLAS_SEARCH_LIBS_WIN_MAIN "")
  281. if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
  282. list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
  283. "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
  284. endif()
  285. if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
  286. list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
  287. "mkl_blas95_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX} mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
  288. endif()
  289. # Add threading/sequential libs
  290. set(BLAS_SEARCH_LIBS_WIN_THREAD "")
  291. if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
  292. # old version
  293. list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
  294. "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
  295. # mkl >= 10.3
  296. list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
  297. "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
  298. endif()
  299. if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
  300. list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
  301. "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
  302. endif()
  303. # Cartesian product of the above
  304. foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
  305. foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
  306. list(APPEND BLAS_SEARCH_LIBS
  307. "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
  308. endforeach()
  309. endforeach()
  310. else()
  311. if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
  312. # old version
  313. list(APPEND BLAS_SEARCH_LIBS
  314. "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
  315. # mkl >= 10.3
  316. list(APPEND BLAS_SEARCH_LIBS
  317. "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
  318. endif()
  319. if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
  320. # old version
  321. list(APPEND BLAS_SEARCH_LIBS
  322. "mkl_blas95 mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
  323. # mkl >= 10.3
  324. list(APPEND BLAS_SEARCH_LIBS
  325. "${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}")
  326. endif()
  327. if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
  328. list(APPEND BLAS_SEARCH_LIBS
  329. "${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}")
  330. endif()
  331. endif()
  332. else()
  333. set(BLAS_mkl_SEARCH_SYMBOL sgemm)
  334. set(_LIBRARIES BLAS_LIBRARIES)
  335. if(WIN32)
  336. # Find the main file (32-bit or 64-bit)
  337. set(BLAS_SEARCH_LIBS_WIN_MAIN "")
  338. if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
  339. list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
  340. "mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
  341. endif()
  342. if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
  343. list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
  344. "mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
  345. endif()
  346. # Add threading/sequential libs
  347. set(BLAS_SEARCH_LIBS_WIN_THREAD "")
  348. if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
  349. list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
  350. "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
  351. endif()
  352. if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
  353. # old version
  354. list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
  355. "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
  356. # mkl >= 10.3
  357. list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
  358. "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
  359. endif()
  360. if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
  361. list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
  362. "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
  363. endif()
  364. # Cartesian product of the above
  365. foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
  366. foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
  367. list(APPEND BLAS_SEARCH_LIBS
  368. "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
  369. endforeach()
  370. endforeach()
  371. else()
  372. if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
  373. # old version
  374. list(APPEND BLAS_SEARCH_LIBS
  375. "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
  376. # mkl >= 10.3
  377. list(APPEND BLAS_SEARCH_LIBS
  378. "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
  379. endif()
  380. if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
  381. # old version
  382. list(APPEND BLAS_SEARCH_LIBS
  383. "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
  384. # mkl >= 10.3
  385. list(APPEND BLAS_SEARCH_LIBS
  386. "${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}")
  387. endif()
  388. if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
  389. list(APPEND BLAS_SEARCH_LIBS
  390. "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}")
  391. endif()
  392. #older vesions of intel mkl libs
  393. if(BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
  394. list(APPEND BLAS_SEARCH_LIBS
  395. "mkl")
  396. list(APPEND BLAS_SEARCH_LIBS
  397. "mkl_ia32")
  398. list(APPEND BLAS_SEARCH_LIBS
  399. "mkl_em64t")
  400. endif()
  401. endif()
  402. endif()
  403. if(BLA_VENDOR MATCHES "^Intel10_64_dyn$" OR BLA_VENDOR STREQUAL "All")
  404. # mkl >= 10.3 with single dynamic library
  405. list(APPEND BLAS_SEARCH_LIBS
  406. "mkl_rt")
  407. endif()
  408. # MKL uses a multitude of partially platform-specific subdirectories:
  409. if(BLA_VENDOR STREQUAL "Intel10_32")
  410. set(BLAS_mkl_ARCH_NAME "ia32")
  411. else()
  412. set(BLAS_mkl_ARCH_NAME "intel64")
  413. endif()
  414. if(WIN32)
  415. set(BLAS_mkl_OS_NAME "win")
  416. elseif(APPLE)
  417. set(BLAS_mkl_OS_NAME "mac")
  418. else()
  419. set(BLAS_mkl_OS_NAME "lin")
  420. endif()
  421. if(DEFINED ENV{MKLROOT})
  422. set(BLAS_mkl_MKLROOT "$ENV{MKLROOT}")
  423. # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
  424. # so we can better detect other relevant libraries in 'compiler' or 'tbb':
  425. get_filename_component(BLAS_mkl_MKLROOT_LAST_DIR "${BLAS_mkl_MKLROOT}" NAME)
  426. if(BLAS_mkl_MKLROOT_LAST_DIR STREQUAL "mkl")
  427. get_filename_component(BLAS_mkl_MKLROOT "${BLAS_mkl_MKLROOT}" DIRECTORY)
  428. endif()
  429. endif()
  430. set(BLAS_mkl_LIB_PATH_SUFFIXES
  431. "compiler/lib" "compiler/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
  432. "compiler/lib/${BLAS_mkl_ARCH_NAME}"
  433. "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
  434. "mkl/lib/${BLAS_mkl_ARCH_NAME}"
  435. "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}")
  436. foreach(IT ${BLAS_SEARCH_LIBS})
  437. string(REPLACE " " ";" SEARCH_LIBS ${IT})
  438. if(NOT ${_LIBRARIES})
  439. check_blas_libraries(
  440. ${_LIBRARIES}
  441. BLAS
  442. ${BLAS_mkl_SEARCH_SYMBOL}
  443. ""
  444. "${SEARCH_LIBS}"
  445. "${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}"
  446. "${BLAS_mkl_MKLROOT}"
  447. "${BLAS_mkl_LIB_PATH_SUFFIXES}"
  448. )
  449. endif()
  450. endforeach()
  451. unset(BLAS_mkl_ILP_MODE)
  452. unset(BLAS_mkl_INTFACE)
  453. unset(BLAS_mkl_THREADING)
  454. unset(BLAS_mkl_OMP)
  455. unset(BLAS_mkl_DLL_SUFFIX)
  456. unset(BLAS_mkl_LM)
  457. unset(BLAS_mkl_LDL)
  458. unset(BLAS_mkl_MKLROOT)
  459. unset(BLAS_mkl_MKLROOT_LAST_DIR)
  460. unset(BLAS_mkl_ARCH_NAME)
  461. unset(BLAS_mkl_OS_NAME)
  462. unset(BLAS_mkl_LIB_PATH_SUFFIXES)
  463. endif()
  464. endif()
  465. endif()
  466. if(BLA_F95)
  467. find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS95_LIBRARIES)
  468. set(BLAS95_FOUND ${BLAS_FOUND})
  469. if(BLAS_FOUND)
  470. set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}")
  471. endif()
  472. endif()
  473. # gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
  474. if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
  475. if(NOT BLAS_LIBRARIES)
  476. check_blas_libraries(
  477. BLAS_LIBRARIES
  478. BLAS
  479. sgemm
  480. ""
  481. "goto2"
  482. ""
  483. ""
  484. ""
  485. )
  486. endif()
  487. endif()
  488. # OpenBLAS? (http://www.openblas.net)
  489. if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
  490. if(NOT BLAS_LIBRARIES)
  491. check_blas_libraries(
  492. BLAS_LIBRARIES
  493. BLAS
  494. sgemm
  495. ""
  496. "openblas"
  497. ""
  498. ""
  499. ""
  500. )
  501. endif()
  502. if(NOT BLAS_LIBRARIES AND (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED))
  503. if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
  504. find_package(Threads)
  505. else()
  506. find_package(Threads REQUIRED)
  507. endif()
  508. check_blas_libraries(
  509. BLAS_LIBRARIES
  510. BLAS
  511. sgemm
  512. ""
  513. "openblas"
  514. "${CMAKE_THREAD_LIBS_INIT}"
  515. ""
  516. ""
  517. )
  518. endif()
  519. endif()
  520. # ArmPL blas library? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
  521. if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All")
  522. # Check for 64bit Integer support
  523. if(BLA_VENDOR MATCHES "_ilp64")
  524. set(BLAS_armpl_LIB "armpl_ilp64")
  525. else()
  526. set(BLAS_armpl_LIB "armpl_lp64")
  527. endif()
  528. # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
  529. if(BLA_VENDOR MATCHES "_mp")
  530. set(BLAS_armpl_LIB "${BLAS_armpl_LIB}_mp")
  531. endif()
  532. if(NOT BLAS_LIBRARIES)
  533. check_blas_libraries(
  534. BLAS_LIBRARIES
  535. BLAS
  536. sgemm
  537. ""
  538. "${BLAS_armpl_LIB}"
  539. ""
  540. ""
  541. ""
  542. )
  543. endif()
  544. endif()
  545. # FLAME's blis library? (https://github.com/flame/blis)
  546. if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
  547. if(NOT BLAS_LIBRARIES)
  548. check_blas_libraries(
  549. BLAS_LIBRARIES
  550. BLAS
  551. sgemm
  552. ""
  553. "blis"
  554. ""
  555. ""
  556. ""
  557. )
  558. endif()
  559. endif()
  560. # BLAS in the ATLAS library? (http://math-atlas.sourceforge.net/)
  561. if(BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
  562. if(NOT BLAS_LIBRARIES)
  563. check_blas_libraries(
  564. BLAS_LIBRARIES
  565. BLAS
  566. dgemm
  567. ""
  568. "blas;f77blas;atlas"
  569. ""
  570. ""
  571. ""
  572. )
  573. endif()
  574. endif()
  575. # BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
  576. if(BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
  577. if(NOT BLAS_LIBRARIES)
  578. check_blas_libraries(
  579. BLAS_LIBRARIES
  580. BLAS
  581. sgemm
  582. ""
  583. "sgemm;dgemm;blas"
  584. ""
  585. ""
  586. ""
  587. )
  588. endif()
  589. endif()
  590. # BLAS in Alpha CXML library?
  591. if(BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
  592. if(NOT BLAS_LIBRARIES)
  593. check_blas_libraries(
  594. BLAS_LIBRARIES
  595. BLAS
  596. sgemm
  597. ""
  598. "cxml"
  599. ""
  600. ""
  601. ""
  602. )
  603. endif()
  604. endif()
  605. # BLAS in Alpha DXML library? (now called CXML, see above)
  606. if(BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
  607. if(NOT BLAS_LIBRARIES)
  608. check_blas_libraries(
  609. BLAS_LIBRARIES
  610. BLAS
  611. sgemm
  612. ""
  613. "dxml"
  614. ""
  615. ""
  616. ""
  617. )
  618. endif()
  619. endif()
  620. # BLAS in Sun Performance library?
  621. if(BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
  622. if(NOT BLAS_LIBRARIES)
  623. check_blas_libraries(
  624. BLAS_LIBRARIES
  625. BLAS
  626. sgemm
  627. "-xlic_lib=sunperf"
  628. "sunperf;sunmath"
  629. ""
  630. ""
  631. ""
  632. )
  633. if(BLAS_LIBRARIES)
  634. set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
  635. endif()
  636. endif()
  637. endif()
  638. # BLAS in SCSL library? (SGI/Cray Scientific Library)
  639. if(BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
  640. if(NOT BLAS_LIBRARIES)
  641. check_blas_libraries(
  642. BLAS_LIBRARIES
  643. BLAS
  644. sgemm
  645. ""
  646. "scsl"
  647. ""
  648. ""
  649. ""
  650. )
  651. endif()
  652. endif()
  653. # BLAS in SGIMATH library?
  654. if(BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
  655. if(NOT BLAS_LIBRARIES)
  656. check_blas_libraries(
  657. BLAS_LIBRARIES
  658. BLAS
  659. sgemm
  660. ""
  661. "complib.sgimath"
  662. ""
  663. ""
  664. ""
  665. )
  666. endif()
  667. endif()
  668. # BLAS in IBM ESSL library? (requires generic BLAS lib, too)
  669. if(BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
  670. if(NOT BLAS_LIBRARIES)
  671. check_blas_libraries(
  672. BLAS_LIBRARIES
  673. BLAS
  674. sgemm
  675. ""
  676. "essl;blas"
  677. ""
  678. ""
  679. ""
  680. )
  681. endif()
  682. endif()
  683. # BLAS in acml library?
  684. if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
  685. if(((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
  686. ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
  687. ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))
  688. )
  689. # try to find acml in "standard" paths
  690. if(WIN32)
  691. file(GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt")
  692. else()
  693. file(GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt")
  694. endif()
  695. if(WIN32)
  696. file(GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples")
  697. else()
  698. file(GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples")
  699. endif()
  700. list(GET _ACML_ROOT 0 _ACML_ROOT)
  701. list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
  702. if(_ACML_ROOT)
  703. get_filename_component(_ACML_ROOT ${_ACML_ROOT} PATH)
  704. if(SIZEOF_INTEGER EQUAL 8)
  705. set(_ACML_PATH_SUFFIX "_int64")
  706. else()
  707. set(_ACML_PATH_SUFFIX "")
  708. endif()
  709. if(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
  710. set(_ACML_COMPILER32 "ifort32")
  711. set(_ACML_COMPILER64 "ifort64")
  712. elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro")
  713. set(_ACML_COMPILER32 "sun32")
  714. set(_ACML_COMPILER64 "sun64")
  715. elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "PGI")
  716. set(_ACML_COMPILER32 "pgi32")
  717. if(WIN32)
  718. set(_ACML_COMPILER64 "win64")
  719. else()
  720. set(_ACML_COMPILER64 "pgi64")
  721. endif()
  722. elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Open64")
  723. # 32 bit builds not supported on Open64 but for code simplicity
  724. # We'll just use the same directory twice
  725. set(_ACML_COMPILER32 "open64_64")
  726. set(_ACML_COMPILER64 "open64_64")
  727. elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "NAG")
  728. set(_ACML_COMPILER32 "nag32")
  729. set(_ACML_COMPILER64 "nag64")
  730. else()
  731. set(_ACML_COMPILER32 "gfortran32")
  732. set(_ACML_COMPILER64 "gfortran64")
  733. endif()
  734. if(BLA_VENDOR STREQUAL "ACML_MP")
  735. set(_ACML_MP_LIB_DIRS
  736. "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
  737. "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib")
  738. else()
  739. set(_ACML_LIB_DIRS
  740. "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
  741. "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib")
  742. endif()
  743. endif()
  744. elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
  745. set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
  746. endif()
  747. if(BLA_VENDOR STREQUAL "ACML_MP")
  748. foreach(BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
  749. check_blas_libraries(
  750. BLAS_LIBRARIES
  751. BLAS
  752. sgemm
  753. "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} ""
  754. )
  755. if(BLAS_LIBRARIES)
  756. break()
  757. endif()
  758. endforeach()
  759. elseif(BLA_VENDOR STREQUAL "ACML_GPU")
  760. foreach(BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
  761. check_blas_libraries(
  762. BLAS_LIBRARIES
  763. BLAS
  764. sgemm
  765. "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} ""
  766. )
  767. if(BLAS_LIBRARIES)
  768. break()
  769. endif()
  770. endforeach()
  771. else()
  772. foreach(BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS})
  773. check_blas_libraries(
  774. BLAS_LIBRARIES
  775. BLAS
  776. sgemm
  777. "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} ""
  778. )
  779. if(BLAS_LIBRARIES)
  780. break()
  781. endif()
  782. endforeach()
  783. endif()
  784. # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
  785. if(NOT BLAS_LIBRARIES)
  786. check_blas_libraries(
  787. BLAS_LIBRARIES
  788. BLAS
  789. sgemm
  790. ""
  791. "acml;acml_mv"
  792. ""
  793. ""
  794. ""
  795. )
  796. endif()
  797. if(NOT BLAS_LIBRARIES)
  798. check_blas_libraries(
  799. BLAS_LIBRARIES
  800. BLAS
  801. sgemm
  802. ""
  803. "acml_mp;acml_mv"
  804. ""
  805. ""
  806. ""
  807. )
  808. endif()
  809. if(NOT BLAS_LIBRARIES)
  810. check_blas_libraries(
  811. BLAS_LIBRARIES
  812. BLAS
  813. sgemm
  814. ""
  815. "acml;acml_mv;CALBLAS"
  816. ""
  817. ""
  818. ""
  819. )
  820. endif()
  821. endif() # ACML
  822. # Apple BLAS library?
  823. if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
  824. if(NOT BLAS_LIBRARIES)
  825. check_blas_libraries(
  826. BLAS_LIBRARIES
  827. BLAS
  828. dgemm
  829. ""
  830. "Accelerate"
  831. ""
  832. ""
  833. ""
  834. )
  835. endif()
  836. endif()
  837. # Apple NAS (vecLib) library?
  838. if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
  839. if(NOT BLAS_LIBRARIES)
  840. check_blas_libraries(
  841. BLAS_LIBRARIES
  842. BLAS
  843. dgemm
  844. ""
  845. "vecLib"
  846. ""
  847. ""
  848. ""
  849. )
  850. endif()
  851. endif()
  852. # Generic BLAS library?
  853. if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
  854. if(NOT BLAS_LIBRARIES)
  855. check_blas_libraries(
  856. BLAS_LIBRARIES
  857. BLAS
  858. sgemm
  859. ""
  860. "blas"
  861. ""
  862. ""
  863. ""
  864. )
  865. endif()
  866. endif()
  867. if(NOT BLA_F95)
  868. find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES)
  869. endif()
  870. # On compilers that implicitly link BLAS (such as ftn, cc, and CC on Cray HPC machines)
  871. # we used a placeholder for empty BLAS_LIBRARIES to get through our logic above.
  872. if(BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
  873. set(BLAS_LIBRARIES "")
  874. endif()
  875. _add_blas_target()
  876. cmake_pop_check_state()
  877. set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})