xref: /aosp_15_r20/external/pytorch/cmake/Modules/FindMKL.cmake (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1# - Find INTEL MKL library
2#
3# This module sets the following variables:
4#  MKL_FOUND - set to true if a library implementing the CBLAS interface is found
5#  MKL_VERSION - best guess of the found mkl version
6#  MKL_INCLUDE_DIR - path to include dir.
7#  MKL_LIBRARIES - list of libraries for base mkl
8#  MKL_OPENMP_TYPE - OpenMP flavor that the found mkl uses: GNU or Intel
9#  MKL_OPENMP_LIBRARY - path to the OpenMP library the found mkl uses
10#  MKL_LAPACK_LIBRARIES - list of libraries to add for lapack
11#  MKL_SCALAPACK_LIBRARIES - list of libraries to add for scalapack
12#  MKL_SOLVER_LIBRARIES - list of libraries to add for the solvers
13#  MKL_CDFT_LIBRARIES - list of libraries to add for the solvers
14
15# Do nothing if MKL_FOUND was set before!
16IF (NOT MKL_FOUND)
17
18SET(MKL_VERSION)
19SET(MKL_INCLUDE_DIR)
20SET(MKL_LIBRARIES)
21SET(MKL_OPENMP_TYPE)
22SET(MKL_OPENMP_LIBRARY)
23SET(MKL_LAPACK_LIBRARIES)
24SET(MKL_SCALAPACK_LIBRARIES)
25SET(MKL_SOLVER_LIBRARIES)
26SET(MKL_CDFT_LIBRARIES)
27
28# Includes
29INCLUDE(CheckTypeSize)
30INCLUDE(CheckFunctionExists)
31
32# Set default value of INTEL_COMPILER_DIR and INTEL_MKL_DIR
33IF (WIN32)
34  IF(DEFINED ENV{MKLProductDir})
35    SET(DEFAULT_INTEL_COMPILER_DIR $ENV{MKLProductDir})
36  ELSE()
37    SET(DEFAULT_INTEL_COMPILER_DIR
38     "C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows")
39  ENDIF()
40  SET(DEFAULT_INTEL_MKL_DIR "${DEFAULT_INTEL_COMPILER_DIR}/mkl")
41  if (EXISTS "${DEFAULT_INTEL_COMPILER_DIR}/mkl/latest")
42    SET(DEFAULT_INTEL_MKL_DIR "${DEFAULT_INTEL_COMPILER_DIR}/mkl/latest")
43  endif()
44ELSE (WIN32)
45  SET(DEFAULT_INTEL_COMPILER_DIR "/opt/intel")
46  SET(DEFAULT_INTEL_MKL_DIR "/opt/intel/mkl")
47  SET(DEFAULT_INTEL_ONEAPI_DIR "/opt/intel/oneapi")
48  if (EXISTS "${DEFAULT_INTEL_ONEAPI_DIR}")
49    SET(DEFAULT_INTEL_COMPILER_DIR "${DEFAULT_INTEL_ONEAPI_DIR}")
50    if (EXISTS "${DEFAULT_INTEL_ONEAPI_DIR}/compiler/latest")
51      SET(DEFAULT_INTEL_COMPILER_DIR "${DEFAULT_INTEL_ONEAPI_DIR}/compiler/latest")
52    endif()
53    if (EXISTS "${DEFAULT_INTEL_ONEAPI_DIR}/mkl/latest")
54      SET(DEFAULT_INTEL_MKL_DIR "${DEFAULT_INTEL_ONEAPI_DIR}/mkl/latest")
55    endif()
56  endif()
57ENDIF (WIN32)
58
59# Intel Compiler Suite
60SET(INTEL_COMPILER_DIR "${DEFAULT_INTEL_COMPILER_DIR}" CACHE STRING
61  "Root directory of the Intel Compiler Suite (contains ipp, mkl, etc.)")
62SET(INTEL_MKL_DIR "${DEFAULT_INTEL_MKL_DIR}" CACHE STRING
63  "Root directory of the Intel MKL (standalone)")
64SET(INTEL_OMP_DIR "${DEFAULT_INTEL_MKL_DIR}" CACHE STRING
65  "Root directory of the Intel OpenMP (standalone)")
66SET(MKL_THREADING "OMP" CACHE STRING "MKL flavor: SEQ, TBB or OMP (default)")
67
68IF (NOT "${MKL_THREADING}" STREQUAL "SEQ" AND
69    NOT "${MKL_THREADING}" STREQUAL "TBB" AND
70    NOT "${MKL_THREADING}" STREQUAL "OMP")
71  MESSAGE(FATAL_ERROR "Invalid MKL_THREADING (${MKL_THREADING}), should be one of: SEQ, TBB, OMP")
72ENDIF()
73
74IF ("${MKL_THREADING}" STREQUAL "TBB" AND NOT TARGET TBB::tbb)
75  MESSAGE(FATAL_ERROR "MKL_THREADING is TBB but TBB is not found")
76ENDIF()
77
78MESSAGE(STATUS "MKL_THREADING = ${MKL_THREADING}")
79
80# Checks
81CHECK_TYPE_SIZE("void*" SIZE_OF_VOIDP)
82IF ("${SIZE_OF_VOIDP}" EQUAL 8)
83  SET(mklvers "intel64")
84  SET(iccvers "intel64")
85  SET(mkl64s "_lp64")
86ELSE ("${SIZE_OF_VOIDP}" EQUAL 8)
87  SET(mklvers "32")
88  SET(iccvers "ia32")
89  SET(mkl64s)
90ENDIF ("${SIZE_OF_VOIDP}" EQUAL 8)
91
92IF(WIN32)
93  IF ("${MKL_THREADING}" STREQUAL "TBB")
94    SET(mklthreads "mkl_tbb_thread")
95    IF (CMAKE_BUILD_TYPE STREQUAL Debug)
96      SET(mklrtls "tbb12_debug")
97    ELSE ()
98      SET(mklrtls "tbb12")
99    ENDIF ()
100  ELSE()
101    SET(mklthreads "mkl_intel_thread")
102    SET(mklrtls "libiomp5md")
103  ENDIF()
104    SET(mklifaces  "intel")
105ELSE(WIN32)
106  IF(CMAKE_COMPILER_IS_GNUCC)
107    IF ("${MKL_THREADING}" STREQUAL "TBB")
108      SET(mklthreads "mkl_tbb_thread")
109      SET(mklrtls "tbb")
110    ELSE()
111      SET(mklthreads "mkl_gnu_thread" "mkl_intel_thread")
112      SET(mklrtls "gomp" "iomp5")
113    ENDIF()
114    SET(mklifaces  "intel" "gf")
115  ELSE(CMAKE_COMPILER_IS_GNUCC)
116    IF ("${MKL_THREADING}" STREQUAL "TBB")
117      SET(mklthreads "mkl_tbb_thread")
118      SET(mklrtls "tbb")
119    ELSE()
120      SET(mklthreads "mkl_intel_thread")
121      SET(mklrtls "iomp5" "guide")
122    ENDIF()
123    SET(mklifaces  "intel")
124  ENDIF (CMAKE_COMPILER_IS_GNUCC)
125ENDIF(WIN32)
126
127# Kernel libraries dynamically loaded
128SET(mklkerlibs "mc" "mc3" "nc" "p4n" "p4m" "p4m3" "p4p" "def")
129SET(mklseq)
130
131# Paths
132SET(saved_CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH})
133SET(saved_CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH})
134IF (EXISTS ${INTEL_COMPILER_DIR})
135  # TODO: diagnostic if dir does not exist
136  SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
137    "${INTEL_COMPILER_DIR}/lib/${iccvers}")
138  IF(MSVC)
139    SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
140      "${INTEL_COMPILER_DIR}/compiler/lib/${iccvers}")
141  ENDIF()
142  IF (APPLE)
143    SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
144      "${INTEL_COMPILER_DIR}/lib")
145  ENDIF()
146  IF (NOT EXISTS ${INTEL_MKL_DIR})
147    SET(INTEL_MKL_DIR "${INTEL_COMPILER_DIR}/mkl")
148  ENDIF()
149ENDIF()
150IF (EXISTS ${INTEL_MKL_DIR})
151  # TODO: diagnostic if dir does not exist
152  SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH}
153    "${INTEL_MKL_DIR}/include")
154  SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
155    "${INTEL_MKL_DIR}/lib/${mklvers}")
156  IF (MSVC)
157    SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
158      "${INTEL_MKL_DIR}/lib/${iccvers}")
159    IF ("${SIZE_OF_VOIDP}" EQUAL 8)
160      SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
161        "${INTEL_MKL_DIR}/win-x64")
162    ENDIF ()
163  ENDIF()
164  IF (APPLE)
165    SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
166      "${INTEL_MKL_DIR}/lib")
167  ENDIF()
168ENDIF()
169
170IF (EXISTS ${INTEL_OMP_DIR})
171  # TODO: diagnostic if dir does not exist
172  SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH}
173    "${INTEL_OMP_DIR}/include")
174  SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
175    "${INTEL_OMP_DIR}/lib/${mklvers}")
176  IF (MSVC)
177    SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
178      "${INTEL_OMP_DIR}/lib/${iccvers}")
179    IF ("${SIZE_OF_VOIDP}" EQUAL 8)
180      SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
181        "${INTEL_OMP_DIR}/win-x64")
182    ENDIF ()
183  ENDIF()
184  IF (APPLE)
185    SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
186      "${INTEL_OMP_DIR}/lib" "${INTEL_COMPILER_DIR}/mac/compiler/lib")
187  ENDIF()
188ENDIF()
189
190MACRO(GET_MKL_LIB_NAMES LIBRARIES INTERFACE MKL64)
191  cmake_parse_arguments("" "" "THREAD" "" ${ARGN})
192  SET(${LIBRARIES} mkl_${INTERFACE}${MKL64} mkl_core)
193  IF(_THREAD)
194    LIST(INSERT ${LIBRARIES} 1 ${_THREAD})
195    IF(UNIX AND ${USE_STATIC_MKL})
196      # The thread library defines symbols required by the other MKL libraries so also add it last
197      LIST(APPEND ${LIBRARIES} ${_THREAD})
198    ENDIF()
199  ENDIF()
200  IF(${USE_STATIC_MKL})
201    IF(UNIX)
202      list(TRANSFORM ${LIBRARIES} PREPEND "lib")
203      list(TRANSFORM ${LIBRARIES} APPEND ".a")
204    ELSE()
205      message(WARNING "Ignoring USE_STATIC_MKL")
206    ENDIF()
207  ENDIF()
208ENDMACRO()
209
210# Try linking multiple libs
211MACRO(CHECK_ALL_LIBRARIES LIBRARIES OPENMP_TYPE OPENMP_LIBRARY _name _list _flags)
212  # This macro checks for the existence of the combination of libraries given by _list.
213  # If the combination is found, this macro checks whether we can link against that library
214  # combination using the name of a routine given by _name using the linker
215  # flags given by _flags.  If the combination of libraries is found and passes
216  # the link test, LIBRARIES is set to the list of complete library paths that
217  # have been found.  Otherwise, LIBRARIES is set to FALSE.
218  # N.B. _prefix is the prefix applied to the names of all cached variables that
219  # are generated internally and marked advanced by this macro.
220  SET(_prefix "${LIBRARIES}")
221  # start checking
222  SET(_libraries_work TRUE)
223  SET(${LIBRARIES})
224  SET(${OPENMP_TYPE})
225  SET(${OPENMP_LIBRARY})
226  SET(_combined_name)
227  SET(_openmp_type)
228  SET(_openmp_library)
229  SET(_paths)
230  IF (NOT MKL_FIND_QUIETLY)
231    set(_str_list)
232    foreach(_elem ${_list})
233      if(_str_list)
234        set(_str_list "${_str_list} - ${_elem}")
235      else()
236        set(_str_list "${_elem}")
237      endif()
238    endforeach(_elem)
239    message(STATUS "Checking for [${_str_list}]")
240  ENDIF ()
241  SET(_found_tbb FALSE)
242  FOREACH(_library ${_list})
243    SET(_combined_name ${_combined_name}_${_library})
244    UNSET(${_prefix}_${_library}_LIBRARY)
245    IF(_libraries_work)
246      IF(${_library} MATCHES "omp")
247        IF(_openmp_type)
248          MESSAGE(FATAL_ERROR "More than one OpenMP libraries appear in the MKL test: ${_list}")
249        ELSEIF(${_library} MATCHES "gomp")
250          SET(_openmp_type "GNU")
251          # Use FindOpenMP to find gomp
252          FIND_PACKAGE(OpenMP QUIET)
253          IF(OPENMP_FOUND)
254            # Test that none of the found library names contains "iomp" (Intel
255            # OpenMP). This doesn't necessarily mean that we have gomp... but it
256            # is probably good enough since on gcc we should already have
257            # OpenMP_CXX_FLAGS="-fopenmp" and OpenMP_CXX_LIB_NAMES="".
258            SET(_found_gomp true)
259            FOREACH(_lib_name ${OpenMP_CXX_LIB_NAMES})
260              IF (_found_gomp AND "${_lib_name}" MATCHES "iomp")
261                SET(_found_gomp false)
262              ENDIF()
263            ENDFOREACH()
264            IF(_found_gomp)
265              SET(${_prefix}_${_library}_LIBRARY ${OpenMP_CXX_FLAGS})
266              SET(_openmp_library "${${_prefix}_${_library}_LIBRARY}")
267            ENDIF()
268          ENDIF(OPENMP_FOUND)
269        ELSEIF(${_library} MATCHES "iomp")
270          SET(_openmp_type "Intel")
271          FIND_LIBRARY(${_prefix}_${_library}_LIBRARY NAMES ${_library})
272          SET(_openmp_library "${${_prefix}_${_library}_LIBRARY}")
273        ELSE()
274          MESSAGE(FATAL_ERROR "Unknown OpenMP flavor: ${_library}")
275        ENDIF()
276      ELSEIF(${_library} STREQUAL "tbb")
277        # Separately handling compiled TBB
278        SET(_found_tbb TRUE)
279      ELSE()
280        IF(MSVC)
281          SET(lib_names ${_library}_dll)
282          SET(lib_names_static ${_library})
283          # Both seek shared and static mkl library.
284          FIND_LIBRARY(${_prefix}_${_library}_LIBRARY NAMES ${lib_names} ${lib_names_static})
285        ELSE()
286          SET(lib_names ${_library})
287          FIND_LIBRARY(${_prefix}_${_library}_LIBRARY NAMES ${lib_names})
288        ENDIF()
289      ENDIF()
290      MARK_AS_ADVANCED(${_prefix}_${_library}_LIBRARY)
291      IF(NOT (${_library} STREQUAL "tbb"))
292        SET(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
293        SET(_libraries_work ${${_prefix}_${_library}_LIBRARY})
294        IF (NOT MKL_FIND_QUIETLY)
295          IF(${_prefix}_${_library}_LIBRARY)
296            MESSAGE(STATUS "  Library ${_library}: ${${_prefix}_${_library}_LIBRARY}")
297          ELSE(${_prefix}_${_library}_LIBRARY)
298            MESSAGE(STATUS "  Library ${_library}: not found")
299          ENDIF(${_prefix}_${_library}_LIBRARY)
300        ENDIF ()
301      ENDIF()
302    ENDIF(_libraries_work)
303  ENDFOREACH(_library ${_list})
304  # Test this combination of libraries.
305  IF(_libraries_work)
306    IF (NOT _found_tbb)
307      SET(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}})
308      SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};${CMAKE_REQUIRED_LIBRARIES}")
309      CHECK_FUNCTION_EXISTS(${_name} ${_prefix}${_combined_name}_WORKS)
310      SET(CMAKE_REQUIRED_LIBRARIES)
311      MARK_AS_ADVANCED(${_prefix}${_combined_name}_WORKS)
312      SET(_libraries_work ${${_prefix}${_combined_name}_WORKS})
313    ENDIF()
314  ENDIF(_libraries_work)
315  # Fin
316  IF(_libraries_work)
317    SET(${OPENMP_TYPE} ${_openmp_type})
318    MARK_AS_ADVANCED(${OPENMP_TYPE})
319    SET(${OPENMP_LIBRARY} ${_openmp_library})
320    MARK_AS_ADVANCED(${OPENMP_LIBRARY})
321  ELSE (_libraries_work)
322    SET(${LIBRARIES})
323    MARK_AS_ADVANCED(${LIBRARIES})
324  ENDIF(_libraries_work)
325ENDMACRO(CHECK_ALL_LIBRARIES)
326
327IF(WIN32)
328  SET(mkl_m "")
329  SET(mkl_pthread "")
330ELSE(WIN32)
331  SET(mkl_m "m")
332  SET(mkl_pthread "pthread")
333ENDIF(WIN32)
334
335IF(UNIX AND NOT APPLE)
336  SET(mkl_dl "${CMAKE_DL_LIBS}")
337ELSE(UNIX AND NOT APPLE)
338  SET(mkl_dl "")
339ENDIF(UNIX AND NOT APPLE)
340
341# Check for version 10/11
342IF (NOT MKL_LIBRARIES)
343  SET(MKL_VERSION 1011)
344ENDIF (NOT MKL_LIBRARIES)
345
346# First: search for parallelized ones with intel thread lib
347IF (NOT "${MKL_THREADING}" STREQUAL "SEQ")
348  FOREACH(mklrtl ${mklrtls} "")
349    FOREACH(mkliface ${mklifaces})
350      FOREACH(mkl64 ${mkl64s} "")
351        FOREACH(mklthread ${mklthreads})
352          IF (NOT MKL_LIBRARIES)
353            GET_MKL_LIB_NAMES(mkl_lib_names "${mkliface}" "${mkl64}" THREAD "${mklthread}")
354            CHECK_ALL_LIBRARIES(MKL_LIBRARIES MKL_OPENMP_TYPE MKL_OPENMP_LIBRARY cblas_sgemm
355              "${mkl_lib_names};${mklrtl};${mkl_pthread};${mkl_m};${mkl_dl}" "")
356          ENDIF (NOT MKL_LIBRARIES)
357        ENDFOREACH(mklthread)
358      ENDFOREACH(mkl64)
359    ENDFOREACH(mkliface)
360  ENDFOREACH(mklrtl)
361ENDIF (NOT "${MKL_THREADING}" STREQUAL "SEQ")
362
363# Second: search for sequential ones
364FOREACH(mkliface ${mklifaces})
365  FOREACH(mkl64 ${mkl64s} "")
366    IF (NOT MKL_LIBRARIES)
367      GET_MKL_LIB_NAMES(mkl_lib_names "${mkliface}" "${mkl64}" THREAD "mkl_sequential")
368      CHECK_ALL_LIBRARIES(MKL_LIBRARIES MKL_OPENMP_TYPE MKL_OPENMP_LIBRARY cblas_sgemm
369        "${mkl_lib_names};${mkl_m};${mkl_dl}" "")
370      IF (MKL_LIBRARIES)
371        SET(mklseq "_sequential")
372      ENDIF (MKL_LIBRARIES)
373    ENDIF (NOT MKL_LIBRARIES)
374  ENDFOREACH(mkl64)
375ENDFOREACH(mkliface)
376
377# First: search for parallelized ones with native pthread lib
378FOREACH(mklrtl ${mklrtls} "")
379  FOREACH(mkliface ${mklifaces})
380    FOREACH(mkl64 ${mkl64s} "")
381      IF (NOT MKL_LIBRARIES)
382        GET_MKL_LIB_NAMES(mkl_lib_names "${mkliface}" "${mkl64}" THREAD "${mklthread}")
383        CHECK_ALL_LIBRARIES(MKL_LIBRARIES MKL_OPENMP_TYPE MKL_OPENMP_LIBRARY cblas_sgemm
384          "${mkl_lib_names};${mklrtl};pthread;${mkl_m};${mkl_dl}" "")
385      ENDIF (NOT MKL_LIBRARIES)
386    ENDFOREACH(mkl64)
387  ENDFOREACH(mkliface)
388ENDFOREACH(mklrtl)
389
390IF (MKL_LIBRARIES)
391  SET(CMAKE_REQUIRED_LIBRARIES ${MKL_LIBRARIES})
392  check_function_exists("cblas_gemm_bf16bf16f32" MKL_HAS_SBGEMM)
393  check_function_exists("cblas_gemm_f16f16f32" MKL_HAS_SHGEMM)
394  set(CMAKE_REQUIRED_LIBRARIES)
395  IF(MKL_HAS_SBGEMM)
396    add_compile_options(-DMKL_HAS_SBGEMM)
397  ENDIF(MKL_HAS_SBGEMM)
398  IF(MKL_HAS_SHGEMM)
399    add_compile_options(-DMKL_HAS_SHGEMM)
400  ENDIF(MKL_HAS_SHGEMM)
401ENDIF (MKL_LIBRARIES)
402
403# Check for older versions
404IF (NOT MKL_LIBRARIES)
405  SET(MKL_VERSION 900)
406  if (USE_STATIC_MKL)
407      message(WARNING "Ignoring USE_STATIC_MKL")
408  endif()
409  CHECK_ALL_LIBRARIES(MKL_LIBRARIES MKL_OPENMP_TYPE MKL_OPENMP_LIBRARY cblas_sgemm
410    "mkl;guide;pthread;m" "")
411ENDIF (NOT MKL_LIBRARIES)
412
413# Include files
414IF (MKL_LIBRARIES)
415  FIND_PATH(MKL_INCLUDE_DIR NAMES "mkl_cblas.h" PATHS "/usr/include/mkl")
416  MARK_AS_ADVANCED(MKL_INCLUDE_DIR)
417ENDIF (MKL_LIBRARIES)
418
419# Other libraries
420IF (MKL_LIBRARIES)
421  FOREACH(mkl64 ${mkl64s} "_core" "")
422    FOREACH(mkls ${mklseq} "")
423      IF (NOT MKL_LAPACK_LIBRARIES)
424        FIND_LIBRARY(MKL_LAPACK_LIBRARIES NAMES "mkl_lapack${mkl64}${mkls}")
425        MARK_AS_ADVANCED(MKL_LAPACK_LIBRARIES)
426      ENDIF (NOT MKL_LAPACK_LIBRARIES)
427      IF (NOT MKL_LAPACK_LIBRARIES)
428        FIND_LIBRARY(MKL_LAPACK_LIBRARIES NAMES "mkl_lapack95${mkl64}${mkls}")
429        MARK_AS_ADVANCED(MKL_LAPACK_LIBRARIES)
430      ENDIF (NOT MKL_LAPACK_LIBRARIES)
431      IF (NOT MKL_SCALAPACK_LIBRARIES)
432        FIND_LIBRARY(MKL_SCALAPACK_LIBRARIES NAMES "mkl_scalapack${mkl64}${mkls}")
433        MARK_AS_ADVANCED(MKL_SCALAPACK_LIBRARIES)
434      ENDIF (NOT MKL_SCALAPACK_LIBRARIES)
435      IF (NOT MKL_SOLVER_LIBRARIES)
436        FIND_LIBRARY(MKL_SOLVER_LIBRARIES NAMES "mkl_solver${mkl64}${mkls}")
437        MARK_AS_ADVANCED(MKL_SOLVER_LIBRARIES)
438      ENDIF (NOT MKL_SOLVER_LIBRARIES)
439      IF (NOT MKL_CDFT_LIBRARIES)
440        FIND_LIBRARY(MKL_CDFT_LIBRARIES NAMES "mkl_cdft${mkl64}${mkls}")
441        MARK_AS_ADVANCED(MKL_CDFT_LIBRARIES)
442      ENDIF (NOT MKL_CDFT_LIBRARIES)
443    ENDFOREACH(mkls)
444  ENDFOREACH(mkl64)
445ENDIF (MKL_LIBRARIES)
446
447# Final
448SET(CMAKE_LIBRARY_PATH ${saved_CMAKE_LIBRARY_PATH})
449SET(CMAKE_INCLUDE_PATH ${saved_CMAKE_INCLUDE_PATH})
450IF (MKL_LIBRARIES AND MKL_INCLUDE_DIR)
451  SET(MKL_FOUND TRUE)
452ELSE (MKL_LIBRARIES AND MKL_INCLUDE_DIR)
453  if (MKL_LIBRARIES AND NOT MKL_INCLUDE_DIR)
454    MESSAGE(WARNING "MKL libraries files are found, but MKL header files are \
455      not. You can get them by `conda install mkl-include` if using conda (if \
456      it is missing, run `conda upgrade -n root conda` first), and \
457      `pip install mkl-devel` if using pip. If build fails with header files \
458      available in the system, please make sure that CMake will search the \
459      directory containing them, e.g., by setting CMAKE_INCLUDE_PATH.")
460  endif()
461  SET(MKL_FOUND FALSE)
462  SET(MKL_VERSION)  # clear MKL_VERSION
463ENDIF (MKL_LIBRARIES AND MKL_INCLUDE_DIR)
464
465# Standard termination
466IF(NOT MKL_FOUND AND MKL_FIND_REQUIRED)
467  MESSAGE(FATAL_ERROR "MKL library not found. Please specify library location \
468    by appending the root directory of the MKL installation to the environment variable CMAKE_PREFIX_PATH.")
469ENDIF(NOT MKL_FOUND AND MKL_FIND_REQUIRED)
470IF(NOT MKL_FIND_QUIETLY)
471  IF(MKL_FOUND)
472    MESSAGE(STATUS "MKL library found")
473  ELSE(MKL_FOUND)
474    MESSAGE(STATUS "MKL library not found")
475  ENDIF(MKL_FOUND)
476ENDIF(NOT MKL_FIND_QUIETLY)
477
478# Do nothing if MKL_FOUND was set before!
479ENDIF (NOT MKL_FOUND)
480