1 #===============================================================================
2 # Copyright 2016-2018 Intel Corporation
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #===============================================================================
17 # Locate Intel(R) MKL installation using MKLROOT or look in
18 # ${CMAKE_CURRENT_SOURCE_DIR}/external
19 #===============================================================================
21 if(MKL_cmake_included)
24 set(MKL_cmake_included true)
25 include("cmake/utils.cmake")
26 include("cmake/options.cmake")
28 # set SKIP_THIS_MKL to true if given configuration is not supported
29 function(maybe_skip_this_mkl LIBNAME)
31 set(SKIP_THIS_MKL False PARENT_SCOPE)
33 # Both mklml_intel and mklml_gnu are OpenMP based.
34 # So in case of TBB link with Intel MKL (RT library) and either set:
35 # MKL_THREADING_LAYER=tbb
36 # to make Intel MKL use TBB threading as well, or
37 # MKL_THREADING_LAYER=sequential
38 # to make Intel MKL be sequential.
39 if (MKLDNN_THREADING STREQUAL "TBB" AND LIBNAME MATCHES "mklml")
40 set(SKIP_THIS_MKL True PARENT_SCOPE)
43 # user doesn't want Intel MKL at all
44 if (MKLDNN_USE_MKL STREQUAL "NONE")
45 set(SKIP_THIS_MKL True PARENT_SCOPE)
48 # user specifies Intel MKL-ML should be used
49 if (MKLDNN_USE_MKL STREQUAL "ML")
50 if (LIBNAME STREQUAL "mkl_rt")
51 set(SKIP_THIS_MKL True PARENT_SCOPE)
55 # user specifies full Intel MKL should be used
56 if (MKLDNN_USE_MKL MATCHES "FULL")
57 if (LIBNAME MATCHES "mklml")
58 set(SKIP_THIS_MKL True PARENT_SCOPE)
62 # avoid using Intel MKL-ML that is not compatible with compiler's OpenMP RT
63 if (MKLDNN_THREADING STREQUAL "OMP:COMP")
64 if ((LIBNAME STREQUAL "mklml_intel" OR LIBNAME STREQUAL "mklml")
65 AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel"))
66 set(SKIP_THIS_MKL True PARENT_SCOPE)
67 elseif (LIBNAME STREQUAL "mklml_gnu"
68 AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
69 set(SKIP_THIS_MKL True PARENT_SCOPE)
71 elseif (MKLDNN_THREADING STREQUAL "OMP:INTEL")
72 if (LIBNAME STREQUAL "mklml_gnu")
73 set(SKIP_THIS_MKL True PARENT_SCOPE)
78 function(detect_mkl LIBNAME)
83 maybe_skip_this_mkl(${LIBNAME})
84 set_if(SKIP_THIS_MKL MAYBE_SKIP_MSG "... skipped")
85 message(STATUS "Detecting Intel(R) MKL: trying ${LIBNAME}${MAYBE_SKIP_MSG}")
91 find_path(MKLINC mkl_cblas.h
92 HINTS ${MKLROOT}/include $ENV{MKLROOT}/include)
94 # skip full Intel MKL while looking for Intel MKL-ML
95 if (MKLINC AND LIBNAME MATCHES "mklml")
96 get_filename_component(__mklinc_root "${MKLINC}" PATH)
97 find_library(tmp_MKLLIB NAMES "mkl_rt"
98 HINTS ${__mklinc_root}/lib/intel64)
99 set_if(tmp_MKLLIB MKLINC "")
100 unset(tmp_MKLLIB CACHE)
104 file(GLOB_RECURSE MKLINC
105 ${CMAKE_CURRENT_SOURCE_DIR}/external/*/mkl_cblas.h)
107 # if user has multiple version under external/ then guess last
108 # one alphabetically is "latest" and warn
109 list(LENGTH MKLINC MKLINCLEN)
110 if(MKLINCLEN GREATER 1)
113 list(GET MKLINC 0 MKLINCLST)
114 set(MKLINC "${MKLINCLST}")
116 get_filename_component(MKLINC ${MKLINC} PATH)
123 get_filename_component(__mklinc_root "${MKLINC}" PATH)
124 find_library(MKLLIB NAMES ${LIBNAME}
125 HINTS ${MKLROOT}/lib ${MKLROOT}/lib/intel64
126 $ENV{MKLROOT}/lib $ENV{MKLROOT}/lib/intel64
127 ${__mklinc_root}/lib ${__mklinc_root}/lib/intel64)
133 set(MKLREDIST ${MKLINC}/../../redist/)
134 find_file(MKLDLL NAMES ${LIBNAME}.dll
137 ${MKLREDIST}/intel64/mkl
138 ${__mklinc_root}/lib)
144 if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
145 get_filename_component(MKLLIBPATH ${MKLLIB} PATH)
146 find_library(MKLIOMP5LIB
147 NAMES "iomp5" "iomp5md" "libiomp5" "libiomp5md"
149 ${MKLLIBPATH}/../../lib
150 ${MKLLIBPATH}/../../../lib/intel64
151 ${MKLLIBPATH}/../../compiler/lib
152 ${MKLLIBPATH}/../../../compiler/lib/intel64)
157 find_file(MKLIOMP5DLL
158 NAMES "libiomp5.dll" "libiomp5md.dll"
159 HINTS ${MKLREDIST}/../compiler ${__mklinc_root}/lib)
169 get_filename_component(MKLLIBPATH "${MKLLIB}" PATH)
170 string(FIND "${MKLLIBPATH}" ${CMAKE_CURRENT_SOURCE_DIR}/external __idx)
173 install(PROGRAMS ${MKLDLL} ${MKLIOMP5DLL}
174 DESTINATION ${CMAKE_INSTALL_BINDIR})
176 install(PROGRAMS ${MKLLIB} ${MKLIOMP5LIB}
177 DESTINATION ${CMAKE_INSTALL_LIBDIR})
182 # Add paths to DLL to %PATH% on Windows
183 get_filename_component(MKLDLLPATH "${MKLDLL}" PATH)
184 append_to_windows_path_list(CTESTCONFIG_PATH "${MKLDLLPATH}")
185 set(CTESTCONFIG_PATH "${CTESTCONFIG_PATH}" PARENT_SCOPE)
188 # TODO: cache the value
189 set(HAVE_MKL TRUE PARENT_SCOPE)
190 set(MKLINC ${MKLINC} PARENT_SCOPE)
191 set(MKLLIB "${MKLLIB}" PARENT_SCOPE)
192 set(MKLDLL "${MKLDLL}" PARENT_SCOPE)
193 if(LIBNAME MATCHES "mklml")
194 set(MKLDNN_USES_MKL "MKLML:SHARED" PARENT_SCOPE)
196 set(MKLDNN_USES_MKL "FULL:SHARED" PARENT_SCOPE)
199 set(MKLIOMP5LIB "${MKLIOMP5LIB}" PARENT_SCOPE)
200 set(MKLIOMP5DLL "${MKLIOMP5DLL}" PARENT_SCOPE)
203 function(set_static_mkl_libs libpath)
204 set_ternary(lib WIN32 "" "lib")
205 set_ternary(a WIN32 ".lib" ".a")
207 if (MKLDNN_THREADING STREQUAL "TBB")
208 set(thr_name "tbb_thread")
209 elseif (MKLDNN_THREADING STREQUAL "OMP:COMP" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
210 set(thr_name "gnu_thread")
212 set(thr_name "intel_thread")
215 find_library(mkl_iface NAMES "${lib}mkl_intel_lp64${a}" HINTS ${libpath})
216 find_library(mkl_thr NAMES "${lib}mkl_${thr_name}${a}" HINTS ${libpath})
217 find_library(mkl_core NAMES "${lib}mkl_core${a}" HINTS ${libpath})
219 set(MKLLIB "${mkl_iface};${mkl_thr};${mkl_core}")
220 if (UNIX AND NOT APPLE)
221 list(APPEND MKLLIB "${mkl_iface};${mkl_thr};${mkl_core}")
223 set_if(UNIX MKLLIB "${MKLLIB};m;dl")
224 set(MKLLIB "${MKLLIB}" PARENT_SCOPE)
227 set(MKLDNN_USES_MKL "")
228 detect_mkl("mklml_intel")
229 detect_mkl("mklml_gnu")
234 if (MKLDNN_USE_MKL STREQUAL "FULL:STATIC")
236 get_filename_component(MKLLIBPATH "${MKLLIB}" PATH)
237 set_static_mkl_libs(${MKLLIBPATH})
238 list(APPEND EXTRA_STATIC_LIBS ${MKLLIB})
239 set(MKLDNN_USES_MKL "FULL:STATIC")
241 list(APPEND EXTRA_SHARED_LIBS ${MKLLIB})
244 add_definitions(-DUSE_MKL -DUSE_CBLAS)
245 include_directories(AFTER ${MKLINC})
247 set(MSG "Intel(R) MKL:")
248 message(STATUS "${MSG} include ${MKLINC}")
249 message(STATUS "${MSG} lib ${MKLLIB}")
251 message(STATUS "${MSG} dll ${MKLDLL}")
254 if (MKLDNN_USE_MKL STREQUAL "NONE")
258 if (NOT MKLDNN_USE_MKL STREQUAL "DEF")
259 set(FAIL_WITHOUT_MKL True)
262 if(DEFINED ENV{FAIL_WITHOUT_MKL} OR DEFINED FAIL_WITHOUT_MKL)
263 set(SEVERITY "FATAL_ERROR")
265 set(SEVERITY "WARNING")
268 "Intel(R) MKL not found. Some performance features may not be "
269 "available. Please run scripts/prepare_mkl.sh to download a minimal "
270 "set of libraries or get a full version from "
271 "https://software.intel.com/en-us/intel-mkl")