MKLConfig.cmake 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. #===============================================================================
  2. # Copyright 2021-2022 Intel Corporation.
  3. #
  4. # This software and the related documents are Intel copyrighted materials, and
  5. # your use of them is governed by the express license under which they were
  6. # provided to you (License). Unless the License provides otherwise, you may not
  7. # use, modify, copy, publish, distribute, disclose or transmit this software or
  8. # the related documents without Intel's prior written permission.
  9. #
  10. # This software and the related documents are provided as is, with no express
  11. # or implied warranties, other than those that are expressly stated in the
  12. # License.
  13. #===============================================================================
  14. #===================================================================
  15. # CMake Config file for Intel(R) oneAPI Math Kernel Library (oneMKL)
  16. #===================================================================
  17. #===============================================================================
  18. # Input parameters
  19. #=================
  20. #-------------
  21. # Main options
  22. #-------------
  23. # MKL_ROOT: oneMKL root directory (May be required for non-standard install locations. Optional otherwise.)
  24. # Default: use location from MKLROOT environment variable or <Full path to this file>/../../../ if MKLROOT is not defined
  25. # MKL_ARCH
  26. # Values: ia32 intel64
  27. # Default: intel64
  28. # MKL_LINK
  29. # Values: static, dynamic, sdl
  30. # Default: dynamic
  31. # Exceptions:- DPC++ doesn't support sdl
  32. # MKL_THREADING
  33. # Values: sequential,
  34. # intel_thread (Intel OpenMP),
  35. # gnu_thread (GNU OpenMP),
  36. # pgi_thread (PGI OpenMP) [PGI support is deprecated],
  37. # tbb_thread
  38. # Default: intel_thread
  39. # Exceptions:- DPC++ defaults to tbb, PGI compiler on Windows defaults to pgi_thread
  40. # MKL_INTERFACE (for MKL_ARCH=intel64 only)
  41. # Values: lp64, ilp64
  42. # GNU or INTEL interface will be selected based on Compiler.
  43. # Default: ilp64
  44. # MKL_MPI
  45. # Values: intelmpi, mpich, openmpi, msmpi, mshpc
  46. # Default: intelmpi
  47. #-----------------------------------
  48. # Special options (OFF by default)
  49. #-----------------------------------
  50. # ENABLE_BLAS95: Enables BLAS Fortran95 API
  51. # ENABLE_LAPACK95: Enables LAPACK Fortran95 API
  52. # ENABLE_BLACS: Enables cluster BLAS library
  53. # ENABLE_CDFT: Enables cluster DFT library
  54. # ENABLE_CPARDISO: Enables cluster PARDISO functionality
  55. # ENABLE_SCALAPACK: Enables cluster LAPACK library
  56. # ENABLE_OMP_OFFLOAD: Enables OpenMP Offload functionality
  57. #
  58. #==================
  59. # Output parameters
  60. #==================
  61. # MKL_ROOT
  62. # oneMKL root directory.
  63. # MKL_INCLUDE
  64. # Use of target_include_directories() is recommended.
  65. # INTERFACE_INCLUDE_DIRECTORIES property is set on mkl_core and mkl_rt libraries.
  66. # Alternatively, this variable can be used directly (not recommended as per Modern CMake)
  67. # MKL_ENV
  68. # Provides all environment variables based on input parameters.
  69. # Currently useful for mkl_rt linking and BLACS on Windows.
  70. # Must be set as an ENVIRONMENT property.
  71. # Example:
  72. # add_test(NAME mytest COMMAND myexe)
  73. # if(MKL_ENV)
  74. # set_tests_properties(mytest PROPERTIES ENVIRONMENT "${MKL_ENV}")
  75. # endif()
  76. #
  77. # MKL::<library name>
  78. # IMPORTED targets to link MKL libraries individually or when using a custom link-line.
  79. # mkl_core and mkl_rt have INTERFACE_* properties set to them.
  80. # Please refer to Intel(R) oneMKL Link Line Advisor for help with linking.
  81. #
  82. # Below INTERFACE targets provide full link-lines for direct use.
  83. # Example:
  84. # target_link_options(<my_linkable_target> PUBLIC $<LINK_ONLY:MKL::MKL>)
  85. #
  86. # MKL::MKL
  87. # Link line for C and Fortran API
  88. # MKL::MKL_DPCPP
  89. # Link line for DPC++ API
  90. #
  91. # Note: For Device API, library linking is not required.
  92. # Compile options can be added from the INTERFACE_COMPILE_OPTIONS property on MKL::MKL_DPCPP
  93. # Include directories can be added from the INTERFACE_INCLUDE_DIRECTORIES property on MKL::MKL_DPCPP
  94. #
  95. # Note: Output parameters' and targets' availability can change
  96. # based on Input parameters and application project languages.
  97. #===============================================================================
  98. function(mkl_message MSG_MODE MSG_TEXT)
  99. if(MSG_MODE STREQUAL "FATAL_ERROR")
  100. message(${MSG_MODE} ${MSG_TEXT})
  101. else()
  102. if(NOT MKL_FIND_QUIETLY)
  103. message(${MSG_MODE} ${MSG_TEXT})
  104. endif()
  105. endif()
  106. endfunction()
  107. if(${CMAKE_VERSION} VERSION_LESS "3.13")
  108. mkl_message(FATAL_ERROR "The minimum supported CMake version is 3.13. You are running version ${CMAKE_VERSION}")
  109. endif()
  110. if(CMAKE_VERSION VERSION_LESS "3.25.2")
  111. mkl_message(STATUS "Upgrade to CMake version 3.25.2 or later for native Intel(R) oneAPI DPC++/C++ Compiler support. You are running version ${CMAKE_VERSION}.")
  112. endif()
  113. include_guard()
  114. include(FindPackageHandleStandardArgs)
  115. if(NOT MKL_LIBRARIES)
  116. # Set CMake policies for well-defined behavior across CMake versions
  117. cmake_policy(SET CMP0011 NEW)
  118. cmake_policy(SET CMP0057 NEW)
  119. # Project Languages
  120. get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES)
  121. list(APPEND MKL_LANGS C CXX Fortran)
  122. foreach(lang ${languages})
  123. if(${lang} IN_LIST MKL_LANGS)
  124. list(APPEND CURR_LANGS ${lang})
  125. endif()
  126. endforeach()
  127. list(REMOVE_DUPLICATES CURR_LANGS)
  128. option(ENABLE_BLAS95 "Enables BLAS Fortran95 API" OFF)
  129. option(ENABLE_LAPACK95 "Enables LAPACK Fortran95 API" OFF)
  130. option(ENABLE_BLACS "Enables cluster BLAS library" OFF)
  131. option(ENABLE_CDFT "Enables cluster DFT library" OFF)
  132. option(ENABLE_CPARDISO "Enables cluster PARDISO functionality" OFF)
  133. option(ENABLE_SCALAPACK "Enables cluster LAPACK library" OFF)
  134. option(ENABLE_OMP_OFFLOAD "Enables OpenMP Offload functionality" OFF)
  135. # Use MPI if any of these are enabled
  136. if(ENABLE_BLACS OR ENABLE_CDFT OR ENABLE_SCALAPACK OR ENABLE_CPARDISO)
  137. set(USE_MPI ON)
  138. endif()
  139. # Check Parameters
  140. function(define_param TARGET_PARAM DEFAULT_PARAM SUPPORTED_LIST)
  141. if(NOT DEFINED ${TARGET_PARAM} AND NOT DEFINED ${DEFAULT_PARAM})
  142. mkl_message(STATUS "${TARGET_PARAM}: Undefined")
  143. elseif(NOT DEFINED ${TARGET_PARAM} AND DEFINED ${DEFAULT_PARAM})
  144. set(${TARGET_PARAM} "${${DEFAULT_PARAM}}" CACHE STRING "Choose ${TARGET_PARAM} options are: ${${SUPPORTED_LIST}}")
  145. foreach(opt ${${DEFAULT_PARAM}})
  146. set(STR_LIST "${STR_LIST} ${opt}")
  147. endforeach()
  148. mkl_message(STATUS "${TARGET_PARAM}: None, set to `${STR_LIST}` by default")
  149. elseif(${SUPPORTED_LIST})
  150. set(ITEM_FOUND 1)
  151. foreach(opt ${${TARGET_PARAM}})
  152. if(NOT ${opt} IN_LIST ${SUPPORTED_LIST})
  153. set(ITEM_FOUND 0)
  154. endif()
  155. endforeach()
  156. if(ITEM_FOUND EQUAL 0)
  157. foreach(opt ${${SUPPORTED_LIST}})
  158. set(STR_LIST "${STR_LIST} ${opt}")
  159. endforeach()
  160. if(${ARGC} EQUAL 3)
  161. mkl_message(FATAL_ERROR "Invalid ${TARGET_PARAM} `${${TARGET_PARAM}}`, options are: ${STR_LIST}")
  162. elseif(${ARGC} EQUAL 4)
  163. mkl_message(${ARGV3} "Invalid ${TARGET_PARAM} `${${TARGET_PARAM}}`, options are: ${STR_LIST}")
  164. set(${TARGET_PARAM} "" PARENT_SCOPE)
  165. endif()
  166. else()
  167. mkl_message(STATUS "${TARGET_PARAM}: ${${TARGET_PARAM}}")
  168. endif()
  169. else()
  170. mkl_message(STATUS "${TARGET_PARAM}: ${${TARGET_PARAM}}")
  171. endif()
  172. endfunction()
  173. #================
  174. # Compiler checks
  175. #================
  176. if(CMAKE_C_COMPILER)
  177. get_filename_component(C_COMPILER_NAME ${CMAKE_C_COMPILER} NAME)
  178. endif()
  179. if(CMAKE_CXX_COMPILER)
  180. get_filename_component(CXX_COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME)
  181. endif()
  182. if(CMAKE_Fortran_COMPILER)
  183. get_filename_component(Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME)
  184. endif()
  185. # Determine Compiler Family
  186. if(CXX_COMPILER_NAME STREQUAL "dpcpp" OR CXX_COMPILER_NAME STREQUAL "dpcpp.exe"
  187. OR CXX_COMPILER_NAME STREQUAL "icpx" OR CXX_COMPILER_NAME STREQUAL "icx.exe")
  188. set(DPCPP_COMPILER ON)
  189. endif()
  190. if(C_COMPILER_NAME MATCHES "^clang" OR CXX_COMPILER_NAME MATCHES "^clang")
  191. set(CLANG_COMPILER ON)
  192. endif()
  193. if(CMAKE_C_COMPILER_ID STREQUAL "PGI" OR CMAKE_CXX_COMPILER_ID STREQUAL "PGI" OR CMAKE_Fortran_COMPILER_ID STREQUAL "PGI"
  194. OR CMAKE_C_COMPILER_ID STREQUAL "NVHPC" OR CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC"
  195. OR CMAKE_Fortran_COMPILER_ID STREQUAL "NVHPC") # PGI 22.9
  196. mkl_message(WARNING "PGI support is deprecated and will be removed in the oneMKL 2025.0 release.")
  197. set(PGI_COMPILER ON)
  198. elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_CXX_COMPILER_ID STREQUAL "Intel" OR CMAKE_Fortran_COMPILER_ID STREQUAL "Intel"
  199. OR CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM" OR CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM")
  200. set(INTEL_COMPILER ON)
  201. else()
  202. if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  203. set(GNU_C_COMPILER ON)
  204. endif()
  205. if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
  206. set(GNU_Fortran_COMPILER ON)
  207. endif()
  208. endif()
  209. # CMake identifies IntelLLVM compilers only after 3.20
  210. if(NOT INTEL_COMPILER)
  211. if(C_COMPILER_NAME STREQUAL "icx" OR C_COMPILER_NAME STREQUAL "icx.exe"
  212. OR CXX_COMPILER_NAME STREQUAL "icpx" OR CXX_COMPILER_NAME STREQUAL "icx.exe"
  213. OR Fortran_COMPILER_NAME STREQUAL "ifx" OR Fortran_COMPILER_NAME STREQUAL "ifx.exe")
  214. set(INTEL_COMPILER ON)
  215. endif()
  216. endif()
  217. if(USE_MPI AND (C_COMPILER_NAME MATCHES "^mpi" OR Fortran_COMPILER_NAME MATCHES "^mpi"))
  218. set(USE_MPI_SCRIPT ON)
  219. endif()
  220. #================
  221. #================
  222. # System-specific
  223. #================
  224. # Extensions
  225. if(UNIX)
  226. set(LIB_PREFIX "lib")
  227. set(LIB_EXT ".a")
  228. set(DLL_EXT ".so")
  229. if(APPLE)
  230. set(DLL_EXT ".dylib")
  231. endif()
  232. set(LINK_PREFIX "-l")
  233. set(LINK_SUFFIX "")
  234. else()
  235. set(LIB_PREFIX "")
  236. set(LIB_EXT ".lib")
  237. set(DLL_EXT "_dll.lib")
  238. set(LINK_PREFIX "")
  239. set(LINK_SUFFIX ".lib")
  240. endif()
  241. # Set target system architecture
  242. if(DPCPP_COMPILER)
  243. set(DEFAULT_MKL_DPCPP_ARCH intel64)
  244. set(MKL_DPCPP_ARCH_LIST intel64)
  245. if(NOT DEFINED MKL_DPCPP_ARCH)
  246. set(MKL_DPCPP_ARCH ${MKL_ARCH})
  247. endif()
  248. define_param(MKL_DPCPP_ARCH DEFAULT_MKL_DPCPP_ARCH MKL_DPCPP_ARCH_LIST STATUS)
  249. if(NOT MKL_DPCPP_ARCH)
  250. set(DPCPP_COMPILER OFF)
  251. mkl_message(STATUS "MKL::MKL_DPCPP target will not be available.")
  252. endif()
  253. endif()
  254. set(DEFAULT_MKL_ARCH intel64)
  255. if(PGI_COMPILER OR ENABLE_OMP_OFFLOAD OR USE_MPI)
  256. set(MKL_ARCH_LIST intel64)
  257. else()
  258. set(MKL_ARCH_LIST ia32 intel64)
  259. endif()
  260. define_param(MKL_ARCH DEFAULT_MKL_ARCH MKL_ARCH_LIST)
  261. #================
  262. #==========
  263. # Setup MKL
  264. #==========
  265. # Set MKL_ROOT directory
  266. if(NOT DEFINED MKL_ROOT)
  267. if(DEFINED ENV{MKLROOT})
  268. set(MKL_ROOT $ENV{MKLROOT})
  269. else()
  270. get_filename_component(MKL_CMAKE_PATH "${CMAKE_CURRENT_LIST_DIR}" REALPATH)
  271. get_filename_component(MKL_ROOT "${MKL_CMAKE_PATH}/../../../" ABSOLUTE)
  272. mkl_message(STATUS "MKL_ROOT ${MKL_ROOT}")
  273. endif()
  274. endif()
  275. string(REPLACE "\\" "/" MKL_ROOT ${MKL_ROOT})
  276. # Define MKL_LINK
  277. if(DPCPP_COMPILER)
  278. set(DEFAULT_MKL_DPCPP_LINK dynamic)
  279. set(MKL_DPCPP_LINK_LIST static dynamic)
  280. if(NOT DEFINED MKL_DPCPP_LINK)
  281. set(MKL_DPCPP_LINK ${MKL_LINK})
  282. endif()
  283. define_param(MKL_DPCPP_LINK DEFAULT_MKL_DPCPP_LINK MKL_DPCPP_LINK_LIST STATUS)
  284. if(NOT MKL_DPCPP_LINK)
  285. set(DPCPP_COMPILER OFF)
  286. mkl_message(STATUS "MKL::MKL_DPCPP target will not be available.")
  287. endif()
  288. endif()
  289. set(DEFAULT_MKL_LINK dynamic)
  290. if(USE_MPI)
  291. set(MKL_LINK_LIST static dynamic)
  292. else()
  293. set(MKL_LINK_LIST static dynamic sdl)
  294. endif()
  295. define_param(MKL_LINK DEFAULT_MKL_LINK MKL_LINK_LIST)
  296. # Define MKL_INTERFACE
  297. if(DPCPP_COMPILER)
  298. if(MKL_INTERFACE AND NOT DEFINED MKL_DPCPP_INTERFACE_FULL)
  299. set(MKL_DPCPP_INTERFACE_FULL intel_${MKL_INTERFACE})
  300. endif()
  301. set(DEFAULT_MKL_DPCPP_INTERFACE intel_ilp64)
  302. set(MKL_DPCPP_INTERFACE_LIST intel_ilp64)
  303. define_param(MKL_DPCPP_INTERFACE_FULL DEFAULT_MKL_DPCPP_INTERFACE MKL_DPCPP_INTERFACE_LIST STATUS)
  304. if(NOT MKL_DPCPP_INTERFACE_FULL)
  305. set(DPCPP_COMPILER OFF)
  306. mkl_message(STATUS "MKL::MKL_DPCPP target will not be available.")
  307. endif()
  308. endif()
  309. if(MKL_ARCH STREQUAL "intel64")
  310. set(IFACE_TYPE intel)
  311. if(GNU_Fortran_COMPILER)
  312. set(IFACE_TYPE gf)
  313. endif()
  314. if(MKL_INTERFACE)
  315. set(MKL_INTERFACE_FULL ${IFACE_TYPE}_${MKL_INTERFACE})
  316. endif()
  317. set(DEFAULT_MKL_INTERFACE ${IFACE_TYPE}_ilp64)
  318. set(MKL_INTERFACE_LIST ${IFACE_TYPE}_ilp64 ${IFACE_TYPE}_lp64)
  319. define_param(MKL_INTERFACE_FULL DEFAULT_MKL_INTERFACE MKL_INTERFACE_LIST)
  320. else()
  321. if(WIN32)
  322. set(MKL_INTERFACE_FULL intel_c)
  323. elseif(NOT APPLE)
  324. if(GNU_Fortran_COMPILER)
  325. set(MKL_INTERFACE_FULL gf)
  326. else()
  327. set(MKL_INTERFACE_FULL intel)
  328. endif()
  329. else()
  330. mkl_message(FATAL_ERROR "OSX does not support MKL_ARCH ia32.")
  331. endif()
  332. endif()
  333. if(MKL_INTERFACE_FULL MATCHES "ilp64")
  334. set(MKL_INTERFACE "ilp64")
  335. else()
  336. set(MKL_INTERFACE "lp64")
  337. endif()
  338. # Define MKL headers
  339. find_path(MKL_H mkl.h
  340. HINTS ${MKL_ROOT}
  341. PATH_SUFFIXES include)
  342. list(APPEND MKL_INCLUDE ${MKL_H})
  343. # Add pre-built F95 Interface Modules
  344. if(INTEL_COMPILER AND (ENABLE_BLAS95 OR ENABLE_LAPACK95))
  345. if(MKL_ARCH STREQUAL "intel64")
  346. list(APPEND MKL_INCLUDE "${MKL_ROOT}/include/${MKL_ARCH}/${MKL_INTERFACE}")
  347. else()
  348. list(APPEND MKL_INCLUDE "${MKL_ROOT}/include/${MKL_ARCH}")
  349. endif()
  350. endif()
  351. # Define MKL_THREADING
  352. # All APIs support sequential threading
  353. # DPC++ API supports TBB threading, but not OpenMP threading
  354. if(DPCPP_COMPILER)
  355. set(MKL_DPCPP_THREADING_LIST "sequential" "tbb_thread")
  356. set(DEFAULT_MKL_DPCPP_THREADING tbb_thread)
  357. if(NOT DEFINED MKL_DPCPP_THREADING)
  358. set(MKL_DPCPP_THREADING ${MKL_THREADING})
  359. endif()
  360. define_param(MKL_DPCPP_THREADING DEFAULT_MKL_DPCPP_THREADING MKL_DPCPP_THREADING_LIST STATUS)
  361. if(NOT MKL_DPCPP_THREADING)
  362. set(DPCPP_COMPILER OFF)
  363. mkl_message(STATUS "MKL::MKL_DPCPP target will not be available.")
  364. endif()
  365. endif()
  366. # C, Fortran API
  367. set(MKL_THREADING_LIST "sequential" "intel_thread" "tbb_thread")
  368. set(DEFAULT_MKL_THREADING intel_thread)
  369. if(PGI_COMPILER)
  370. # PGI compiler supports PGI OpenMP threading, additionally
  371. list(APPEND MKL_THREADING_LIST pgi_thread)
  372. # PGI compiler does not support TBB threading
  373. list(REMOVE_ITEM MKL_THREADING_LIST tbb_thread)
  374. if(WIN32)
  375. # PGI 19.10 and 20.1 on Windows, do not support Intel OpenMP threading
  376. list(REMOVE_ITEM MKL_THREADING_LIST intel_thread)
  377. set(DEFAULT_MKL_THREADING pgi_thread)
  378. endif()
  379. elseif(GNU_C_COMPILER OR GNU_Fortran_COMPILER OR CLANG_COMPILER)
  380. list(APPEND MKL_THREADING_LIST gnu_thread)
  381. else()
  382. # Intel and Microsoft compilers
  383. # Nothing to do, only for completeness
  384. endif()
  385. define_param(MKL_THREADING DEFAULT_MKL_THREADING MKL_THREADING_LIST)
  386. # Define MKL_MPI
  387. if(USE_MPI)
  388. set(DEFAULT_MKL_MPI intelmpi)
  389. if(UNIX)
  390. if(APPLE)
  391. # Override defaults for OSX
  392. set(DEFAULT_MKL_MPI mpich)
  393. set(MKL_MPI_LIST mpich)
  394. else()
  395. set(MKL_MPI_LIST intelmpi openmpi mpich mpich2)
  396. endif()
  397. else()
  398. # Windows
  399. set(MKL_MPI_LIST intelmpi mshpc msmpi)
  400. endif()
  401. define_param(MKL_MPI DEFAULT_MKL_MPI MKL_MPI_LIST)
  402. # MSMPI is now called MSHPC. MSMPI option exists for backward compatibility.
  403. if(MKL_MPI STREQUAL "mshpc")
  404. set(MKL_MPI msmpi)
  405. endif()
  406. find_package_handle_standard_args(MKL REQUIRED_VARS MKL_MPI)
  407. endif()
  408. # Checkpoint - Verify if required options are defined
  409. find_package_handle_standard_args(MKL REQUIRED_VARS MKL_ROOT MKL_ARCH MKL_INCLUDE MKL_LINK MKL_THREADING MKL_INTERFACE_FULL)
  410. # Provides a list of IMPORTED targets for the project
  411. if(NOT DEFINED MKL_IMPORTED_TARGETS)
  412. set(MKL_IMPORTED_TARGETS "")
  413. endif()
  414. # Clear temporary variables
  415. set(MKL_C_COPT "")
  416. set(MKL_F_COPT "")
  417. set(MKL_SDL_COPT "")
  418. set(MKL_CXX_COPT "")
  419. set(MKL_DPCPP_COPT "")
  420. set(MKL_DPCPP_LOPT "")
  421. set(MKL_OFFLOAD_COPT "")
  422. set(MKL_OFFLOAD_LOPT "")
  423. set(MKL_SUPP_LINK "") # Other link options. Usually at the end of the link-line.
  424. set(MKL_DPCPP_SUPP_LINK "")
  425. set(MKL_LINK_LINE "")
  426. set(MKL_DPCPP_LINK_LINE "")
  427. set(MKL_ENV_PATH "") # Temporary variable to work with PATH
  428. set(MKL_ENV "") # Exported environment variables
  429. # Modify PATH variable to make it CMake-friendly
  430. set(OLD_PATH $ENV{PATH})
  431. string(REPLACE ";" "\;" OLD_PATH "${OLD_PATH}")
  432. # Compiler options
  433. if(GNU_C_COMPILER OR GNU_Fortran_COMPILER)
  434. if(MKL_ARCH STREQUAL "ia32")
  435. list(APPEND MKL_C_COPT -m32)
  436. list(APPEND MKL_CXX_COPT -m32)
  437. list(APPEND MKL_F_COPT -m32)
  438. else()
  439. list(APPEND MKL_C_COPT -m64)
  440. list(APPEND MKL_CXX_COPT -m64)
  441. list(APPEND MKL_F_COPT -m64)
  442. endif()
  443. endif()
  444. # Additonal compiler & linker options
  445. if(DPCPP_COMPILER)
  446. list(APPEND MKL_DPCPP_COPT "-fsycl")
  447. list(APPEND MKL_DPCPP_LOPT "-fsycl")
  448. if(MKL_DPCPP_LINK STREQUAL "static")
  449. list(APPEND MKL_DPCPP_LOPT "-fsycl-device-code-split=per_kernel")
  450. endif()
  451. endif()
  452. if(ENABLE_OMP_OFFLOAD)
  453. if(MKL_LINK STREQUAL "static")
  454. list(APPEND MKL_OFFLOAD_LOPT "-fsycl-device-code-split=per_kernel")
  455. endif()
  456. endif()
  457. # For OpenMP Offload
  458. if(ENABLE_OMP_OFFLOAD)
  459. if(WIN32)
  460. if(OPENMP_VERSION VERSION_GREATER_EQUAL "5.1")
  461. if("Fortran" IN_LIST CURR_LANGS)
  462. list(APPEND MKL_OFFLOAD_COPT -Qiopenmp -Qopenmp-targets:spir64 -DONEMKL_USE_OPENMP_VERSION=202011)
  463. else()
  464. list(APPEND MKL_OFFLOAD_COPT -Qiopenmp -Qopenmp-targets:spir64 -Qopenmp-version:51 -DONEMKL_USE_OPENMP_VERSION=202011)
  465. endif()
  466. else()
  467. list(APPEND MKL_OFFLOAD_COPT -Qiopenmp -Qopenmp-targets:spir64)
  468. endif()
  469. # -MD and -MDd are manually added here because offload functionality uses DPC++ runtime.
  470. if(CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo")
  471. list(APPEND MKL_OFFLOAD_COPT -MDd)
  472. else()
  473. list(APPEND MKL_OFFLOAD_COPT -MD)
  474. endif()
  475. list(APPEND MKL_OFFLOAD_LOPT -Qiopenmp -Qopenmp-targets:spir64 -fsycl)
  476. set(SKIP_LIBPATH ON)
  477. else()
  478. if(OPENMP_VERSION VERSION_GREATER_EQUAL "5.1")
  479. if("Fortran" IN_LIST CURR_LANGS)
  480. list(APPEND MKL_OFFLOAD_COPT -fiopenmp -fopenmp-targets=spir64 -DONEMKL_USE_OPENMP_VERSION=202011)
  481. else()
  482. list(APPEND MKL_OFFLOAD_COPT -fiopenmp -fopenmp-targets=spir64 -fopenmp-version=51 -DONEMKL_USE_OPENMP_VERSION=202011)
  483. endif()
  484. else ()
  485. list(APPEND MKL_OFFLOAD_COPT -fiopenmp -fopenmp-targets=spir64)
  486. endif()
  487. list(APPEND MKL_OFFLOAD_LOPT -fiopenmp -fopenmp-targets=spir64 -fsycl)
  488. if(APPLE)
  489. list(APPEND MKL_SUPP_LINK -lc++)
  490. else()
  491. list(APPEND MKL_SUPP_LINK -lstdc++)
  492. endif()
  493. endif()
  494. endif()
  495. # For selected Interface
  496. if(DPCPP_COMPILER)
  497. list(INSERT MKL_DPCPP_COPT 0 "-DMKL_ILP64")
  498. endif()
  499. if(MKL_INTERFACE_FULL)
  500. if(MKL_ARCH STREQUAL "ia32")
  501. if(GNU_Fortran_COMPILER)
  502. set(MKL_SDL_IFACE_ENV "GNU")
  503. endif()
  504. else()
  505. if(GNU_Fortran_COMPILER)
  506. set(MKL_SDL_IFACE_ENV "GNU,${MKL_INTERFACE}")
  507. else()
  508. set(MKL_SDL_IFACE_ENV "${MKL_INTERFACE}")
  509. endif()
  510. if(MKL_INTERFACE STREQUAL "ilp64")
  511. if("Fortran" IN_LIST CURR_LANGS)
  512. if(INTEL_COMPILER)
  513. if(WIN32)
  514. list(APPEND MKL_F_COPT "-4I8")
  515. else()
  516. list(APPEND MKL_F_COPT "-i8")
  517. endif()
  518. elseif(GNU_Fortran_COMPILER)
  519. list(APPEND MKL_F_COPT "-fdefault-integer-8")
  520. elseif(PGI_COMPILER)
  521. list(APPEND MKL_F_COPT "-i8")
  522. endif()
  523. endif()
  524. list(INSERT MKL_C_COPT 0 "-DMKL_ILP64")
  525. list(INSERT MKL_SDL_COPT 0 "-DMKL_ILP64")
  526. list(INSERT MKL_CXX_COPT 0 "-DMKL_ILP64")
  527. list(INSERT MKL_OFFLOAD_COPT 0 "-DMKL_ILP64")
  528. else()
  529. # lp64
  530. endif()
  531. endif()
  532. if(MKL_SDL_IFACE_ENV)
  533. string(TOUPPER ${MKL_SDL_IFACE_ENV} MKL_SDL_IFACE_ENV)
  534. endif()
  535. endif() # MKL_INTERFACE_FULL
  536. # All MKL Libraries
  537. if(DPCPP_COMPILER)
  538. set(MKL_DPCPP_IFACE_LIB mkl_${MKL_DPCPP_INTERFACE_FULL})
  539. if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo" AND MKL_DPCPP_THREADING STREQUAL "tbb_thread")
  540. set(MKL_DPCPP_THREAD mkl_tbb_threadd)
  541. else()
  542. set(MKL_DPCPP_THREAD mkl_${MKL_DPCPP_THREADING})
  543. endif()
  544. endif()
  545. if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo")
  546. set(MKL_SYCL mkl_sycld)
  547. else()
  548. set(MKL_SYCL mkl_sycl)
  549. endif()
  550. set(MKL_IFACE_LIB mkl_${MKL_INTERFACE_FULL})
  551. set(MKL_CORE mkl_core)
  552. if(WIN32 AND CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo" AND MKL_THREADING STREQUAL "tbb_thread")
  553. set(MKL_THREAD mkl_tbb_threadd)
  554. else()
  555. set(MKL_THREAD mkl_${MKL_THREADING})
  556. endif()
  557. set(MKL_SDL mkl_rt)
  558. if(MKL_ARCH STREQUAL "ia32")
  559. set(MKL_BLAS95 mkl_blas95)
  560. set(MKL_LAPACK95 mkl_lapack95)
  561. else()
  562. set(MKL_BLAS95 mkl_blas95_${MKL_INTERFACE})
  563. set(MKL_LAPACK95 mkl_lapack95_${MKL_INTERFACE})
  564. endif()
  565. # BLACS
  566. set(MKL_BLACS mkl_blacs_${MKL_MPI}_${MKL_INTERFACE})
  567. if(UNIX AND NOT APPLE AND MKL_MPI MATCHES "mpich")
  568. # MPICH is compatible with INTELMPI Wrappers on Linux
  569. set(MKL_BLACS mkl_blacs_intelmpi_${MKL_INTERFACE})
  570. endif()
  571. if(WIN32)
  572. if(MKL_MPI STREQUAL "msmpi")
  573. if("Fortran" IN_LIST CURR_LANGS)
  574. list(APPEND MKL_SUPP_LINK "msmpifec.lib")
  575. endif()
  576. # MSMPI and MSHPC are supported with the same BLACS library
  577. set(MKL_BLACS mkl_blacs_msmpi_${MKL_INTERFACE})
  578. if(NOT MKL_LINK STREQUAL "static")
  579. set(MKL_BLACS mkl_blacs_${MKL_INTERFACE})
  580. set(MKL_BLACS_ENV MSMPI)
  581. endif()
  582. elseif(MKL_MPI STREQUAL "intelmpi" AND NOT MKL_LINK STREQUAL "static")
  583. set(MKL_BLACS mkl_blacs_${MKL_INTERFACE})
  584. set(MKL_BLACS_ENV INTELMPI)
  585. endif()
  586. endif()
  587. # CDFT & SCALAPACK
  588. set(MKL_CDFT mkl_cdft_core)
  589. set(MKL_SCALAPACK mkl_scalapack_${MKL_INTERFACE})
  590. if(UNIX AND NOT APPLE)
  591. if(MKL_LINK STREQUAL "static" OR MKL_DPCPP_LINK STREQUAL "static")
  592. set(START_GROUP "-Wl,--start-group")
  593. set(END_GROUP "-Wl,--end-group")
  594. if(DPCPP_COMPILER)
  595. set(DPCPP_EXPORT_DYNAMIC "-Wl,-export-dynamic")
  596. endif()
  597. if(ENABLE_OMP_OFFLOAD)
  598. set(EXPORT_DYNAMIC "-Wl,-export-dynamic")
  599. endif()
  600. endif()
  601. if(MKL_LINK STREQUAL "dynamic")
  602. set(MKL_RPATH "-Wl,-rpath=$<TARGET_FILE_DIR:MKL::${MKL_CORE}>")
  603. if((GNU_Fortran_COMPILER OR PGI_COMPILER) AND "Fortran" IN_LIST CURR_LANGS)
  604. set(NO_AS_NEEDED -Wl,--no-as-needed)
  605. endif()
  606. endif()
  607. if(MKL_DPCPP_LINK STREQUAL "dynamic")
  608. set(MKL_DPCPP_RPATH "-Wl,-rpath=$<TARGET_FILE_DIR:MKL::${MKL_CORE}>")
  609. endif()
  610. if(MKL_LINK STREQUAL "sdl")
  611. set(MKL_RPATH "-Wl,-rpath=$<TARGET_FILE_DIR:MKL::${MKL_SDL}>")
  612. endif()
  613. endif()
  614. # Create a list of requested libraries, based on input options (MKL_LIBRARIES)
  615. # Create full link-line in MKL_LINK_LINE
  616. if(DPCPP_COMPILER)
  617. list(APPEND MKL_DPCPP_LIBRARIES ${MKL_SYCL} ${MKL_DPCPP_IFACE_LIB} ${MKL_DPCPP_THREAD} ${MKL_CORE})
  618. list(APPEND MKL_DPCPP_LINK_LINE ${MKL_DPCPP_LOPT} ${DPCPP_EXPORT_DYNAMIC} ${NO_AS_NEEDED} ${MKL_DPCPP_RPATH}
  619. MKL::${MKL_SYCL} ${START_GROUP} MKL::${MKL_DPCPP_IFACE_LIB} MKL::${MKL_DPCPP_THREAD} MKL::${MKL_CORE} ${END_GROUP})
  620. endif()
  621. list(APPEND MKL_LINK_LINE $<IF:$<BOOL:${ENABLE_OMP_OFFLOAD}>,${MKL_OFFLOAD_LOPT},>
  622. ${EXPORT_DYNAMIC} ${NO_AS_NEEDED} ${MKL_RPATH})
  623. if(ENABLE_BLAS95)
  624. list(APPEND MKL_LIBRARIES ${MKL_BLAS95})
  625. list(APPEND MKL_LINK_LINE MKL::${MKL_BLAS95})
  626. endif()
  627. if(ENABLE_LAPACK95)
  628. list(APPEND MKL_LIBRARIES ${MKL_LAPACK95})
  629. list(APPEND MKL_LINK_LINE MKL::${MKL_LAPACK95})
  630. endif()
  631. if(ENABLE_SCALAPACK)
  632. list(APPEND MKL_LIBRARIES ${MKL_SCALAPACK})
  633. list(APPEND MKL_LINK_LINE MKL::${MKL_SCALAPACK})
  634. endif()
  635. if(ENABLE_OMP_OFFLOAD AND NOT MKL_LINK STREQUAL "sdl")
  636. list(APPEND MKL_LIBRARIES ${MKL_SYCL})
  637. list(APPEND MKL_LINK_LINE MKL::${MKL_SYCL})
  638. endif()
  639. list(APPEND MKL_LINK_LINE ${START_GROUP})
  640. if(ENABLE_CDFT)
  641. list(APPEND MKL_LIBRARIES ${MKL_CDFT})
  642. list(APPEND MKL_LINK_LINE MKL::${MKL_CDFT})
  643. endif()
  644. if(MKL_LINK STREQUAL "sdl")
  645. list(APPEND MKL_LIBRARIES ${MKL_SDL})
  646. list(APPEND MKL_LINK_LINE MKL::${MKL_SDL})
  647. else()
  648. list(APPEND MKL_LIBRARIES ${MKL_IFACE_LIB} ${MKL_THREAD} ${MKL_CORE})
  649. list(APPEND MKL_LINK_LINE MKL::${MKL_IFACE_LIB} MKL::${MKL_THREAD} MKL::${MKL_CORE})
  650. endif()
  651. if(USE_MPI)
  652. list(APPEND MKL_LIBRARIES ${MKL_BLACS})
  653. list(APPEND MKL_LINK_LINE MKL::${MKL_BLACS})
  654. endif()
  655. list(APPEND MKL_LINK_LINE ${END_GROUP})
  656. # Find all requested libraries
  657. list(APPEND MKL_REQUESTED_LIBRARIES ${MKL_LIBRARIES})
  658. if(DPCPP_COMPILER)
  659. # If DPCPP_COMPILER is still ON, MKL_DPCPP_ARCH, MKL_DPCPP_LINK, and MKL_DPCPP_IFACE_LIB are the same as MKL_ARCH, MKL_LINK, and MKL_IFACE_LIB.
  660. # Hence we can combine the libraries and find them in the following for loop.
  661. # Note that MKL_DPCPP_THREADING and MKL_THREADING could be different because of the default value.
  662. list(APPEND MKL_REQUESTED_LIBRARIES ${MKL_DPCPP_LIBRARIES})
  663. list(REMOVE_DUPLICATES MKL_REQUESTED_LIBRARIES)
  664. endif()
  665. foreach(lib ${MKL_REQUESTED_LIBRARIES})
  666. unset(${lib}_file CACHE)
  667. if(MKL_LINK STREQUAL "static" AND NOT ${lib} STREQUAL ${MKL_SDL})
  668. find_library(${lib}_file ${LIB_PREFIX}${lib}${LIB_EXT}
  669. PATHS ${MKL_ROOT}
  670. PATH_SUFFIXES "lib" "lib/${MKL_ARCH}")
  671. add_library(MKL::${lib} STATIC IMPORTED)
  672. else()
  673. find_library(${lib}_file NAMES ${LIB_PREFIX}${lib}${DLL_EXT} ${lib}
  674. PATHS ${MKL_ROOT}
  675. PATH_SUFFIXES "lib" "lib/${MKL_ARCH}")
  676. add_library(MKL::${lib} SHARED IMPORTED)
  677. endif()
  678. find_package_handle_standard_args(MKL REQUIRED_VARS ${lib}_file)
  679. # CMP0111, implemented in CMake 3.20+ requires a shared library target on Windows
  680. # to be defined with IMPLIB and LOCATION property.
  681. # It also requires a static library target to be defined with LOCATION property.
  682. # Setting the policy to OLD usage, using cmake_policy() does not work as of 3.20.0, hence the if-else below.
  683. if(WIN32 AND NOT MKL_LINK STREQUAL "static")
  684. set_target_properties(MKL::${lib} PROPERTIES IMPORTED_IMPLIB "${${lib}_file}")
  685. # Find corresponding DLL
  686. set(MKL_DLL_GLOB ${lib}.*.dll)
  687. file(GLOB MKL_DLL_FILE "${MKL_ROOT}/redist/${MKL_ARCH}/${MKL_DLL_GLOB}"
  688. "${MKL_ROOT}/../redist/${MKL_ARCH}/${MKL_DLL_GLOB}"
  689. "${MKL_ROOT}/../redist/${MKL_ARCH}/mkl/${MKL_DLL_GLOB}"
  690. "${MKL_ROOT}/bin/${MKL_DLL_GLOB}" # Support for Conda directory layout
  691. )
  692. if(NOT ${lib} STREQUAL ${MKL_IFACE_LIB} AND NOT ${lib} STREQUAL ${MKL_BLAS95} AND NOT ${lib} STREQUAL ${MKL_LAPACK95}) # Windows IFACE libs are static only
  693. list(LENGTH MKL_DLL_FILE MKL_DLL_FILE_LEN)
  694. if(MKL_DLL_FILE_LEN)
  695. # in case multiple versions of the same dll are found, select the highest version
  696. list(SORT MKL_DLL_FILE)
  697. list(REVERSE MKL_DLL_FILE)
  698. list(GET MKL_DLL_FILE 0 MKL_DLL_FILE)
  699. mkl_message(STATUS "Found DLL: ${MKL_DLL_FILE}")
  700. set_target_properties(MKL::${lib} PROPERTIES IMPORTED_LOCATION "${MKL_DLL_FILE}")
  701. else()
  702. mkl_message(FATAL_ERROR "${MKL_DLL_GLOB} not found")
  703. endif()
  704. endif()
  705. else()
  706. set_target_properties(MKL::${lib} PROPERTIES IMPORTED_LOCATION "${${lib}_file}")
  707. endif()
  708. list(APPEND MKL_IMPORTED_TARGETS MKL::${lib})
  709. endforeach()
  710. # Threading selection
  711. if(MKL_THREADING STREQUAL "tbb_thread" OR MKL_DPCPP_THREADING STREQUAL "tbb_thread")
  712. find_package(TBB REQUIRED CONFIG COMPONENTS tbb)
  713. if(MKL_THREADING STREQUAL "tbb_thread")
  714. set(MKL_THREAD_LIB $<TARGET_LINKER_FILE:TBB::tbb>)
  715. set(MKL_SDL_THREAD_ENV "TBB")
  716. endif()
  717. if(MKL_DPCPP_THREADING STREQUAL "tbb_thread")
  718. set(MKL_DPCPP_THREAD_LIB $<TARGET_LINKER_FILE:TBB::tbb>)
  719. endif()
  720. get_property(TBB_LIB TARGET TBB::tbb PROPERTY IMPORTED_LOCATION_RELEASE)
  721. get_filename_component(TBB_LIB_DIR ${TBB_LIB} DIRECTORY)
  722. if(UNIX)
  723. if(CMAKE_SKIP_BUILD_RPATH)
  724. set(TBB_LINK "-L${TBB_LIB_DIR} -ltbb")
  725. else()
  726. set(TBB_LINK "-Wl,-rpath,${TBB_LIB_DIR} -L${TBB_LIB_DIR} -ltbb")
  727. endif()
  728. if(MKL_THREADING STREQUAL "tbb_thread")
  729. list(APPEND MKL_SUPP_LINK ${TBB_LINK})
  730. if(APPLE)
  731. list(APPEND MKL_SUPP_LINK -lc++)
  732. else()
  733. list(APPEND MKL_SUPP_LINK -lstdc++)
  734. endif()
  735. endif()
  736. if(MKL_DPCPP_THREADING STREQUAL "tbb_thread")
  737. list(APPEND MKL_DPCPP_SUPP_LINK ${TBB_LINK})
  738. endif()
  739. endif()
  740. if(WIN32 OR APPLE)
  741. set(MKL_ENV_PATH ${TBB_LIB_DIR})
  742. endif()
  743. endif()
  744. if(NOT MKL_THREADING STREQUAL "tbb_thread" AND MKL_THREADING MATCHES "_thread")
  745. if(MKL_THREADING STREQUAL "pgi_thread")
  746. list(APPEND MKL_SUPP_LINK -mp -pgf90libs)
  747. set(MKL_SDL_THREAD_ENV "PGI")
  748. elseif(MKL_THREADING STREQUAL "gnu_thread")
  749. list(APPEND MKL_SUPP_LINK -lgomp)
  750. set(MKL_SDL_THREAD_ENV "GNU")
  751. else()
  752. # intel_thread
  753. if(UNIX)
  754. set(MKL_OMP_LIB iomp5)
  755. set(LIB_EXT ".so")
  756. if(APPLE)
  757. set(LIB_EXT ".dylib")
  758. endif()
  759. else()
  760. set(MKL_OMP_LIB libiomp5md)
  761. endif()
  762. set(MKL_SDL_THREAD_ENV "INTEL")
  763. set(OMP_LIBNAME ${LIB_PREFIX}${MKL_OMP_LIB}${LIB_EXT})
  764. find_library(OMP_LIBRARY ${OMP_LIBNAME}
  765. HINTS $ENV{LIB} $ENV{LIBRARY_PATH} $ENV{MKLROOT} ${MKL_ROOT} $ENV{CMPLR_ROOT}
  766. PATH_SUFFIXES "lib" "lib/${MKL_ARCH}"
  767. "lib/${MKL_ARCH}_lin" "lib/${MKL_ARCH}_win"
  768. "linux/compiler/lib/${MKL_ARCH}"
  769. "linux/compiler/lib/${MKL_ARCH}_lin"
  770. "windows/compiler/lib/${MKL_ARCH}"
  771. "windows/compiler/lib/${MKL_ARCH}_win"
  772. "../compiler/lib/${MKL_ARCH}_lin" "../compiler/lib/${MKL_ARCH}_win"
  773. "../compiler/lib/${MKL_ARCH}" "../compiler/lib" "compiler/lib"
  774. "../../compiler/latest/linux/compiler/lib/${MKL_ARCH}"
  775. "../../compiler/latest/linux/compiler/lib/${MKL_ARCH}_lin"
  776. "../../compiler/latest/windows/compiler/lib/${MKL_ARCH}"
  777. "../../compiler/latest/windows/compiler/lib/${MKL_ARCH}_win"
  778. "../../compiler/latest/mac/compiler/lib")
  779. if(WIN32)
  780. set(OMP_DLLNAME ${LIB_PREFIX}${MKL_OMP_LIB}.dll)
  781. find_path(OMP_DLL_DIR ${OMP_DLLNAME}
  782. HINTS $ENV{LIB} $ENV{LIBRARY_PATH} $ENV{MKLROOT} ${MKL_ROOT} $ENV{CMPLR_ROOT}
  783. PATH_SUFFIXES "redist/${MKL_ARCH}"
  784. "redist/${MKL_ARCH}_win" "redist/${MKL_ARCH}_win/compiler"
  785. "../redist/${MKL_ARCH}/compiler" "../compiler/lib"
  786. "../../compiler/latest/windows/redist/${MKL_ARCH}_win"
  787. "../../compiler/latest/windows/redist/${MKL_ARCH}_win/compiler"
  788. "../../compiler/latest/windows/compiler/redist/${MKL_ARCH}_win"
  789. "../../compiler/latest/windows/compiler/redist/${MKL_ARCH}_win/compiler")
  790. find_package_handle_standard_args(MKL REQUIRED_VARS OMP_DLL_DIR)
  791. set(MKL_ENV_PATH "${OMP_DLL_DIR}")
  792. endif()
  793. if(WIN32 AND SKIP_LIBPATH)
  794. # Only for Intel OpenMP Offload
  795. set(OMP_LINK "libiomp5md.lib")
  796. else()
  797. set(OMP_LINK "${OMP_LIBRARY}")
  798. if(CMAKE_C_COMPILER_ID STREQUAL "PGI" OR CMAKE_Fortran_COMPILER_ID STREQUAL "PGI")
  799. # Disable PGI OpenMP runtime for correct work of Intel OpenMP runtime
  800. list(APPEND MKL_SUPP_LINK -nomp)
  801. endif()
  802. endif()
  803. find_package_handle_standard_args(MKL REQUIRED_VARS OMP_LIBRARY OMP_LINK)
  804. set(MKL_THREAD_LIB ${OMP_LINK})
  805. endif()
  806. elseif(MKL_THREADING STREQUAL "sequential")
  807. # Sequential threading
  808. set(MKL_SDL_THREAD_ENV "SEQUENTIAL")
  809. endif() # MKL_THREADING
  810. if(UNIX)
  811. if(DPCPP_COMPILER)
  812. list(APPEND MKL_DPCPP_SUPP_LINK -lm -ldl -lpthread)
  813. endif()
  814. list(APPEND MKL_SUPP_LINK -lm -ldl -lpthread)
  815. endif()
  816. if(DPCPP_COMPILER OR ENABLE_OMP_OFFLOAD)
  817. if(WIN32)
  818. # Detect sycl library version
  819. if(NOT DEFINED SYCL_LIB_VER_CACHE)
  820. set(SYCL_LIB_VER "")
  821. find_library(SYCL_LIB_DIR ${LIB_PREFIX}sycl${LIB_EXT}
  822. HINTS $ENV{LIB} $ENV{CMPLR_ROOT}
  823. PATH_SUFFIXES "windows/lib")
  824. if(NOT SYCL_LIB_DIR)
  825. foreach(ver RANGE 6 99)
  826. find_library(SYCL_LIB_DIR ${LIB_PREFIX}sycl${ver}${LIB_EXT}
  827. HINTS $ENV{LIB} $ENV{CMPLR_ROOT}
  828. PATH_SUFFIXES "windows/lib")
  829. if(SYCL_LIB_DIR)
  830. set(SYCL_LIB_VER ${ver})
  831. break()
  832. endif()
  833. endforeach()
  834. endif()
  835. set(SYCL_LIB_VER_CACHE ${SYCL_LIB_VER} CACHE STRING "")
  836. endif()
  837. if(DPCPP_COMPILER)
  838. if(CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo")
  839. list(APPEND MKL_DPCPP_SUPP_LINK ${LINK_PREFIX}sycl${SYCL_LIB_VER_CACHE}d${LINK_SUFFIX})
  840. else()
  841. list(APPEND MKL_DPCPP_SUPP_LINK ${LINK_PREFIX}sycl${SYCL_LIB_VER_CACHE}${LINK_SUFFIX})
  842. endif()
  843. endif()
  844. if(ENABLE_OMP_OFFLOAD)
  845. if(CMAKE_BUILD_TYPE MATCHES "Debug|DebInfo")
  846. list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycl${SYCL_LIB_VER_CACHE}d${LINK_SUFFIX})
  847. else()
  848. list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycl${SYCL_LIB_VER_CACHE}${LINK_SUFFIX})
  849. endif()
  850. endif()
  851. else()
  852. if(DPCPP_COMPILER)
  853. list(APPEND MKL_DPCPP_SUPP_LINK ${LINK_PREFIX}sycl${LINK_SUFFIX})
  854. endif()
  855. if(ENABLE_OMP_OFFLOAD)
  856. list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}sycl${LINK_SUFFIX})
  857. endif()
  858. endif()
  859. if(DPCPP_COMPILER)
  860. list(APPEND MKL_DPCPP_SUPP_LINK ${LINK_PREFIX}OpenCL${LINK_SUFFIX})
  861. endif()
  862. if(ENABLE_OMP_OFFLOAD)
  863. list(APPEND MKL_SUPP_LINK ${LINK_PREFIX}OpenCL${LINK_SUFFIX})
  864. endif()
  865. endif()
  866. # Setup link types based on input options
  867. set(LINK_TYPES "")
  868. if(DPCPP_COMPILER)
  869. if(NOT TARGET MKL::MKL_DPCPP)
  870. add_library(MKL::MKL_DPCPP INTERFACE IMPORTED GLOBAL)
  871. endif()
  872. target_compile_options(MKL::MKL_DPCPP INTERFACE $<$<COMPILE_LANGUAGE:CXX>:${MKL_DPCPP_COPT}>)
  873. target_link_libraries(MKL::MKL_DPCPP INTERFACE ${MKL_DPCPP_LINK_LINE} ${MKL_DPCPP_THREAD_LIB} ${MKL_DPCPP_SUPP_LINK})
  874. list(APPEND LINK_TYPES MKL::MKL_DPCPP)
  875. endif()
  876. # Single target for all C, Fortran link-lines
  877. if(NOT TARGET MKL::MKL)
  878. add_library(MKL::MKL INTERFACE IMPORTED GLOBAL)
  879. endif()
  880. target_compile_options(MKL::MKL INTERFACE
  881. $<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:${MKL_C_COPT}>
  882. $<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,Fortran>:${MKL_F_COPT}>
  883. $<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:${MKL_CXX_COPT}>
  884. $<IF:$<BOOL:${ENABLE_OMP_OFFLOAD}>,${MKL_OFFLOAD_COPT},>)
  885. target_link_libraries(MKL::MKL INTERFACE ${MKL_LINK_LINE} ${MKL_THREAD_LIB} ${MKL_SUPP_LINK})
  886. list(APPEND LINK_TYPES MKL::MKL)
  887. foreach(link ${LINK_TYPES})
  888. # Set properties on all INTERFACE targets
  889. target_include_directories(${link} BEFORE INTERFACE "${MKL_INCLUDE}")
  890. list(APPEND MKL_IMPORTED_TARGETS ${link})
  891. endforeach(link) # LINK_TYPES
  892. if(MKL_LINK STREQUAL "sdl")
  893. list(APPEND MKL_ENV "MKL_INTERFACE_LAYER=${MKL_SDL_IFACE_ENV}" "MKL_THREADING_LAYER=${MKL_SDL_THREAD_ENV}")
  894. endif()
  895. if(WIN32 AND NOT MKL_LINK STREQUAL "static")
  896. list(APPEND MKL_ENV "MKL_BLACS_MPI=${MKL_BLACS_ENV}")
  897. endif()
  898. # Add MKL dynamic libraries if RPATH is not defined on Unix
  899. if(UNIX AND CMAKE_SKIP_BUILD_RPATH)
  900. if(MKL_LINK STREQUAL "sdl")
  901. set(MKL_LIB_DIR $<TARGET_FILE_DIR:MKL::${MKL_SDL}>)
  902. else()
  903. set(MKL_LIB_DIR $<TARGET_FILE_DIR:MKL::${MKL_CORE}>)
  904. endif()
  905. if(APPLE)
  906. list(APPEND MKL_ENV "DYLD_LIBRARY_PATH=${MKL_LIB_DIR}\;$ENV{DYLD_LIBRARY_PATH}")
  907. else()
  908. list(APPEND MKL_ENV "LD_LIBRARY_PATH=${MKL_LIB_DIR}\;$ENV{LD_LIBRARY_PATH}")
  909. endif()
  910. endif()
  911. # Add MKL dynamic libraries to PATH on Windows
  912. if(WIN32 AND NOT MKL_LINK STREQUAL "static")
  913. get_filename_component(MKL_DLL_DIR ${MKL_DLL_FILE} DIRECTORY)
  914. set(MKL_ENV_PATH "${MKL_DLL_DIR}\;${MKL_ENV_PATH}")
  915. endif()
  916. if(MKL_ENV_PATH)
  917. list(APPEND MKL_ENV "PATH=${MKL_ENV_PATH}\;${OLD_PATH}")
  918. if(APPLE)
  919. list(APPEND MKL_ENV "DYLD_LIBRARY_PATH=${MKL_ENV_PATH}\:${OLD_PATH}")
  920. endif()
  921. endif()
  922. unset(MKL_DLL_FILE)
  923. endif() # MKL_LIBRARIES