1### 2# 3# @copyright (c) 2009-2014 The University of Tennessee and The University 4# of Tennessee Research Foundation. 5# All rights reserved. 6# @copyright (c) 2012-2016 Inria. All rights reserved. 7# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. 8# 9### 10# 11# - Find BLAS EXTENDED for MORSE projects: find include dirs and libraries 12# 13# This module allows to find BLAS libraries by calling the official FindBLAS module 14# and handles the creation of different library lists whether the user wishes to link 15# with a sequential BLAS or a multihreaded (BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES). 16# BLAS is detected with a FindBLAS call then if the BLAS vendor is Intel10_64lp, ACML 17# or IBMESSLMT then the module attempts to find the corresponding multithreaded libraries. 18# 19# The following variables have been added to manage links with sequential or multithreaded 20# versions: 21# BLAS_INCLUDE_DIRS - BLAS include directories 22# BLAS_LIBRARY_DIRS - Link directories for BLAS libraries 23# BLAS_SEQ_LIBRARIES - BLAS component libraries to be linked (sequential) 24# BLAS_PAR_LIBRARIES - BLAS component libraries to be linked (multithreaded) 25 26#============================================================================= 27# Copyright 2012-2013 Inria 28# Copyright 2012-2013 Emmanuel Agullo 29# Copyright 2012-2013 Mathieu Faverge 30# Copyright 2012 Cedric Castagnede 31# Copyright 2013-2016 Florent Pruvost 32# 33# Distributed under the OSI-approved BSD License (the "License"); 34# see accompanying file MORSE-Copyright.txt for details. 35# 36# This software is distributed WITHOUT ANY WARRANTY; without even the 37# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 38# See the License for more information. 39#============================================================================= 40# (To distribute this file outside of Morse, substitute the full 41# License text for the above reference.) 42 43# macro to factorize this call 44include(CMakeFindDependencyMacro) 45macro(find_package_blas) 46 if(BLASEXT_FIND_REQUIRED) 47 if(BLASEXT_FIND_QUIETLY) 48 find_dependency(BLAS REQUIRED QUIET) 49 else() 50 find_dependency(BLAS REQUIRED) 51 endif() 52 else() 53 if(BLASEXT_FIND_QUIETLY) 54 find_dependency(BLAS QUIET) 55 else() 56 find_dependency(BLAS) 57 endif() 58 endif() 59endmacro() 60 61# add a cache variable to let the user specify the BLAS vendor 62set(BLA_VENDOR "" CACHE STRING "list of possible BLAS vendor: 63 Open, Eigen, Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT, 64 Intel10_32 (intel mkl v10 32 bit), 65 Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), 66 Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model), 67 Intel( older versions of mkl 32 and 64 bit), 68 ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") 69 70if(NOT BLASEXT_FIND_QUIETLY) 71 message(STATUS "In FindBLASEXT") 72 message(STATUS "If you want to force the use of one specific library, " 73 "\n please specify the BLAS vendor by setting -DBLA_VENDOR=blas_vendor_name" 74 "\n at cmake configure.") 75 message(STATUS "List of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, " 76 "\n DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT, Intel10_32 (intel mkl v10 32 bit)," 77 "\n Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model)," 78 "\n Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," 79 "\n Intel( older versions of mkl 32 and 64 bit)," 80 "\n ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") 81endif() 82 83if (NOT BLAS_FOUND) 84 # First try to detect two cases: 85 # 1: only SEQ libs are handled 86 # 2: both SEQ and PAR libs are handled 87 find_package_blas() 88endif () 89 90# detect the cases where SEQ and PAR libs are handled 91if(BLA_VENDOR STREQUAL "All" AND 92 (BLAS_mkl_core_LIBRARY OR BLAS_mkl_core_dll_LIBRARY) 93 ) 94 set(BLA_VENDOR "Intel") 95 if(BLAS_mkl_intel_LIBRARY) 96 set(BLA_VENDOR "Intel10_32") 97 endif() 98 if(BLAS_mkl_intel_lp64_LIBRARY) 99 set(BLA_VENDOR "Intel10_64lp") 100 endif() 101 if(NOT BLASEXT_FIND_QUIETLY) 102 message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" 103 "\n have also potentially detected some multithreaded BLAS libraries from the MKL." 104 "\n We try to find both libraries lists (Sequential/Multithreaded).") 105 endif() 106 set(BLAS_FOUND "") 107elseif(BLA_VENDOR STREQUAL "All" AND BLAS_acml_LIBRARY) 108 set(BLA_VENDOR "ACML") 109 if(NOT BLASEXT_FIND_QUIETLY) 110 message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" 111 "\n have also potentially detected some multithreaded BLAS libraries from the ACML." 112 "\n We try to find both libraries lists (Sequential/Multithreaded).") 113 endif() 114 set(BLAS_FOUND "") 115elseif(BLA_VENDOR STREQUAL "All" AND BLAS_essl_LIBRARY) 116 set(BLA_VENDOR "IBMESSL") 117 if(NOT BLASEXT_FIND_QUIETLY) 118 message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" 119 "\n have also potentially detected some multithreaded BLAS libraries from the ESSL." 120 "\n We try to find both libraries lists (Sequential/Multithreaded).") 121 endif() 122 set(BLAS_FOUND "") 123endif() 124 125# Intel case 126if(BLA_VENDOR MATCHES "Intel*") 127 128 ### 129 # look for include path if the BLAS vendor is Intel 130 ### 131 132 # gather system include paths 133 unset(_inc_env) 134 if(WIN32) 135 string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") 136 else() 137 string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") 138 list(APPEND _inc_env "${_path_env}") 139 string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") 140 list(APPEND _inc_env "${_path_env}") 141 string(REPLACE ":" ";" _path_env "$ENV{CPATH}") 142 list(APPEND _inc_env "${_path_env}") 143 string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") 144 list(APPEND _inc_env "${_path_env}") 145 endif() 146 list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") 147 list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") 148 set(ENV_MKLROOT "$ENV{MKLROOT}") 149 if (ENV_MKLROOT) 150 list(APPEND _inc_env "${ENV_MKLROOT}/include") 151 endif() 152 list(REMOVE_DUPLICATES _inc_env) 153 154 # find mkl.h inside known include paths 155 set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") 156 if(BLAS_INCDIR) 157 set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") 158 find_path(BLAS_mkl.h_INCLUDE_DIRS 159 NAMES mkl.h 160 HINTS ${BLAS_INCDIR}) 161 else() 162 if(BLAS_DIR) 163 set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") 164 find_path(BLAS_mkl.h_INCLUDE_DIRS 165 NAMES mkl.h 166 HINTS ${BLAS_DIR} 167 PATH_SUFFIXES include) 168 else() 169 set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") 170 find_path(BLAS_mkl.h_INCLUDE_DIRS 171 NAMES mkl.h 172 HINTS ${_inc_env}) 173 endif() 174 endif() 175 mark_as_advanced(BLAS_mkl.h_INCLUDE_DIRS) 176 ## Print status if not found 177 ## ------------------------- 178 #if (NOT BLAS_mkl.h_INCLUDE_DIRS AND MORSE_VERBOSE) 179 # Print_Find_Header_Status(blas mkl.h) 180 #endif () 181 set(BLAS_INCLUDE_DIRS "") 182 if(BLAS_mkl.h_INCLUDE_DIRS) 183 list(APPEND BLAS_INCLUDE_DIRS "${BLAS_mkl.h_INCLUDE_DIRS}" ) 184 endif() 185 186 ### 187 # look for libs 188 ### 189 # if Intel 10 64 bit -> look for sequential and multithreaded versions 190 if(BLA_VENDOR MATCHES "Intel10_64lp*") 191 192 ## look for the sequential version 193 set(BLA_VENDOR "Intel10_64lp_seq") 194 if(NOT BLASEXT_FIND_QUIETLY) 195 message(STATUS "Look for the sequential version Intel10_64lp_seq") 196 endif() 197 find_package_blas() 198 if(BLAS_FOUND) 199 set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") 200 else() 201 set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") 202 endif() 203 204 ## look for the multithreaded version 205 set(BLA_VENDOR "Intel10_64lp") 206 if(NOT BLASEXT_FIND_QUIETLY) 207 message(STATUS "Look for the multithreaded version Intel10_64lp") 208 endif() 209 find_package_blas() 210 if(BLAS_FOUND) 211 set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") 212 else() 213 set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") 214 endif() 215 216 else() 217 218 if(BLAS_FOUND) 219 set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") 220 else() 221 set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") 222 endif() 223 224 endif() 225 226 # ACML case 227elseif(BLA_VENDOR MATCHES "ACML*") 228 229 ## look for the sequential version 230 set(BLA_VENDOR "ACML") 231 find_package_blas() 232 if(BLAS_FOUND) 233 set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") 234 else() 235 set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") 236 endif() 237 238 ## look for the multithreaded version 239 set(BLA_VENDOR "ACML_MP") 240 find_package_blas() 241 if(BLAS_FOUND) 242 set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") 243 else() 244 set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") 245 endif() 246 247 # IBMESSL case 248elseif(BLA_VENDOR MATCHES "IBMESSL*") 249 250 ## look for the sequential version 251 set(BLA_VENDOR "IBMESSL") 252 find_package_blas() 253 if(BLAS_FOUND) 254 set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") 255 else() 256 set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") 257 endif() 258 259 ## look for the multithreaded version 260 set(BLA_VENDOR "IBMESSLMT") 261 find_package_blas() 262 if(BLAS_FOUND) 263 set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") 264 else() 265 set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") 266 endif() 267 268else() 269 270 if(BLAS_FOUND) 271 # define the SEQ libs as the BLAS_LIBRARIES 272 set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") 273 else() 274 set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") 275 endif() 276 set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") 277 278endif() 279 280 281if(BLAS_SEQ_LIBRARIES) 282 set(BLAS_LIBRARIES "${BLAS_SEQ_LIBRARIES}") 283endif() 284 285# extract libs paths 286# remark: because it is not given by find_package(BLAS) 287set(BLAS_LIBRARY_DIRS "") 288string(REPLACE " " ";" BLAS_LIBRARIES "${BLAS_LIBRARIES}") 289foreach(blas_lib ${BLAS_LIBRARIES}) 290 if (EXISTS "${blas_lib}") 291 get_filename_component(a_blas_lib_dir "${blas_lib}" PATH) 292 list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" ) 293 else() 294 string(REPLACE "-L" "" blas_lib "${blas_lib}") 295 if (EXISTS "${blas_lib}") 296 list(APPEND BLAS_LIBRARY_DIRS "${blas_lib}" ) 297 else() 298 get_filename_component(a_blas_lib_dir "${blas_lib}" PATH) 299 if (EXISTS "${a_blas_lib_dir}") 300 list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" ) 301 endif() 302 endif() 303 endif() 304endforeach() 305if (BLAS_LIBRARY_DIRS) 306 list(REMOVE_DUPLICATES BLAS_LIBRARY_DIRS) 307endif () 308 309# check that BLAS has been found 310# --------------------------------- 311include(FindPackageHandleStandardArgs) 312if(BLA_VENDOR MATCHES "Intel*") 313 if(BLA_VENDOR MATCHES "Intel10_64lp*") 314 if(NOT BLASEXT_FIND_QUIETLY) 315 message(STATUS "BLAS found is Intel MKL:" 316 "\n we manage two lists of libs, one sequential and one parallel if found" 317 "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") 318 message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") 319 endif() 320 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 321 BLAS_SEQ_LIBRARIES 322 BLAS_LIBRARY_DIRS 323 BLAS_INCLUDE_DIRS) 324 if(BLAS_PAR_LIBRARIES) 325 if(NOT BLASEXT_FIND_QUIETLY) 326 message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") 327 endif() 328 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 329 BLAS_PAR_LIBRARIES) 330 endif() 331 else() 332 if(NOT BLASEXT_FIND_QUIETLY) 333 message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") 334 endif() 335 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 336 BLAS_SEQ_LIBRARIES 337 BLAS_LIBRARY_DIRS 338 BLAS_INCLUDE_DIRS) 339 endif() 340elseif(BLA_VENDOR MATCHES "ACML*") 341 if(NOT BLASEXT_FIND_QUIETLY) 342 message(STATUS "BLAS found is ACML:" 343 "\n we manage two lists of libs, one sequential and one parallel if found" 344 "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") 345 message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") 346 endif() 347 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 348 BLAS_SEQ_LIBRARIES 349 BLAS_LIBRARY_DIRS) 350 if(BLAS_PAR_LIBRARIES) 351 if(NOT BLASEXT_FIND_QUIETLY) 352 message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") 353 endif() 354 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 355 BLAS_PAR_LIBRARIES) 356 endif() 357elseif(BLA_VENDOR MATCHES "IBMESSL*") 358 if(NOT BLASEXT_FIND_QUIETLY) 359 message(STATUS "BLAS found is ESSL:" 360 "\n we manage two lists of libs, one sequential and one parallel if found" 361 "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") 362 message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") 363 endif() 364 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 365 BLAS_SEQ_LIBRARIES 366 BLAS_LIBRARY_DIRS) 367 if(BLAS_PAR_LIBRARIES) 368 if(NOT BLASEXT_FIND_QUIETLY) 369 message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") 370 endif() 371 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 372 BLAS_PAR_LIBRARIES) 373 endif() 374else() 375 if(NOT BLASEXT_FIND_QUIETLY) 376 message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") 377 endif() 378 find_package_handle_standard_args(BLASEXT DEFAULT_MSG 379 BLAS_SEQ_LIBRARIES 380 BLAS_LIBRARY_DIRS) 381endif() 382 383# Callers expect BLAS_FOUND to be set as well. 384set(BLAS_FOUND BLASEXT_FOUND) 385