FindBLASEXT.cmake 13.6 KB
Newer Older
1 2 3 4 5
###
#
# @copyright (c) 2009-2014 The University of Tennessee and The University
#                          of Tennessee Research Foundation.
#                          All rights reserved.
6
# @copyright (c) 2012-2017 Inria. All rights reserved.
7 8 9 10 11 12 13 14 15
# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
#
###
#
# - Find BLAS EXTENDED for MORSE projects: find include dirs and libraries
#
# This module allows to find BLAS libraries by calling the official FindBLAS module
# and handles the creation of different library lists whether the user wishes to link
# with a sequential BLAS or a multihreaded (BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES).
16 17
# BLAS is detected with a FindBLAS call then if the BLAS vendor is Intel10_64lp, ACML
# or IBMESSLMT then the module attempts to find the corresponding multithreaded libraries.
18 19 20
#
# The following variables have been added to manage links with sequential or multithreaded
# versions:
21 22 23 24 25 26 27 28 29 30 31 32 33 34
#  BLAS_INCLUDE_DIRS       - BLAS include directories
#  BLAS_LIBRARY_DIRS       - Link directories for BLAS libraries
#  BLAS_SEQ_LIBRARIES      - BLAS component libraries to be linked (sequential)
#  BLAS_SEQ_COMPILER_FLAGS - uncached list of required compiler flags (including -I for mkl headers).
#  BLAS_SEQ_LINKER_FLAGS   - uncached list of required linker flags (excluding -l
#    and -L)
#  BLAS_PAR_LIBRARIES      - BLAS component libraries to be linked (multithreaded)
#  BLAS_PAR_COMPILER_FLAGS - uncached list of required compiler flags (including -I for mkl headers)
#  BLAS_PAR_LINKER_FLAGS   - uncached list of required linker flags (excluding -l
#    and -L)
#  BLASEXT_FOUND           - if a BLAS has been found
#  BLASEXT_LIBRARIES       - Idem BLAS_LIBRARIES
#  BLASEXT_INCLUDE_DIRS    - Idem BLAS_INCLUDE_DIRS
#  BLASEXT_LIBRARY_DIRS    - Idem BLAS_LIBRARY_DIRS
35 36 37 38 39 40

#=============================================================================
# Copyright 2012-2013 Inria
# Copyright 2012-2013 Emmanuel Agullo
# Copyright 2012-2013 Mathieu Faverge
# Copyright 2012      Cedric Castagnede
41
# Copyright 2013-2017 Florent Pruvost
42 43 44 45 46 47 48 49 50 51 52
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file MORSE-Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of Morse, substitute the full
#  License text for the above reference.)

53 54 55 56
# Macro to factorize this call. required arguments allows to decide if
# the REQUIRED option must be given to find_package calls
macro(find_package_blas required)
  if(BLASEXT_FIND_REQUIRED AND required)
PRUVOST Florent's avatar
PRUVOST Florent committed
57 58
    if(BLASEXT_FIND_QUIETLY)
      find_package(BLAS REQUIRED QUIET)
59
    else()
PRUVOST Florent's avatar
PRUVOST Florent committed
60 61 62 63 64 65 66 67 68
      find_package(BLAS REQUIRED)
    endif()
  else()
    if(BLASEXT_FIND_QUIETLY)
      find_package(BLAS QUIET)
    else()
      find_package(BLAS)
    endif()
  endif()
69
endmacro()
70 71 72

# add a cache variable to let the user specify the BLAS vendor
set(BLA_VENDOR "" CACHE STRING "list of possible BLAS vendor:
73
    Open, Eigen, Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT,
74 75 76 77 78 79
    Intel10_32 (intel mkl v10 32 bit),
    Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model),
    Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),
    Intel( older versions of mkl 32 and 64 bit),
    ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")

80
if(NOT BLASEXT_FIND_QUIETLY)
PRUVOST Florent's avatar
PRUVOST Florent committed
81 82 83 84 85 86 87 88 89 90
  message(STATUS "In FindBLASEXT")
  message(STATUS "If you want to force the use of one specific library, "
    "\n   please specify the BLAS vendor by setting -DBLA_VENDOR=blas_vendor_name"
    "\n   at cmake configure.")
  message(STATUS "List of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, "
    "\n   DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT, Intel10_32 (intel mkl v10 32 bit),"
    "\n   Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model),"
    "\n   Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model),"
    "\n   Intel( older versions of mkl 32 and 64 bit),"
    "\n   ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic")
91
endif()
92 93

if (NOT BLAS_FOUND)
94 95 96
  # First blas detection in order to decide if we should look for a
  # multitheaded version
  find_package_blas(0)
97 98 99 100
endif ()

# detect the cases where SEQ and PAR libs are handled
if(BLA_VENDOR STREQUAL "All" AND
PRUVOST Florent's avatar
PRUVOST Florent committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
    (BLAS_mkl_core_LIBRARY OR BLAS_mkl_core_dll_LIBRARY)
    )
  set(BLA_VENDOR "Intel")
  if(BLAS_mkl_intel_LIBRARY)
    set(BLA_VENDOR "Intel10_32")
  endif()
  if(BLAS_mkl_intel_lp64_LIBRARY)
    set(BLA_VENDOR "Intel10_64lp")
  endif()
  if(NOT BLASEXT_FIND_QUIETLY)
    message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
      "\n   have also potentially detected some multithreaded BLAS libraries from the MKL."
      "\n   We try to find both libraries lists (Sequential/Multithreaded).")
  endif()
  set(BLAS_FOUND "")
116
elseif(BLA_VENDOR STREQUAL "All" AND BLAS_acml_LIBRARY)
PRUVOST Florent's avatar
PRUVOST Florent committed
117 118 119 120 121 122 123
  set(BLA_VENDOR "ACML")
  if(NOT BLASEXT_FIND_QUIETLY)
    message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
      "\n   have also potentially detected some multithreaded BLAS libraries from the ACML."
      "\n   We try to find both libraries lists (Sequential/Multithreaded).")
  endif()
  set(BLAS_FOUND "")
124
elseif(BLA_VENDOR STREQUAL "All" AND BLAS_essl_LIBRARY)
PRUVOST Florent's avatar
PRUVOST Florent committed
125 126 127 128 129 130 131
  set(BLA_VENDOR "IBMESSL")
  if(NOT BLASEXT_FIND_QUIETLY)
    message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we"
      "\n   have also potentially detected some multithreaded BLAS libraries from the ESSL."
      "\n   We try to find both libraries lists (Sequential/Multithreaded).")
  endif()
  set(BLAS_FOUND "")
132 133 134 135 136
endif()

# Intel case
if(BLA_VENDOR MATCHES "Intel*")

PRUVOST Florent's avatar
PRUVOST Florent committed
137 138 139
  ###
  # look for include path if the BLAS vendor is Intel
  ###
140

PRUVOST Florent's avatar
PRUVOST Florent committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  # gather system include paths
  unset(_inc_env)
  if(WIN32)
    string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}")
  else()
    string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}")
    list(APPEND _inc_env "${_path_env}")
    string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}")
    list(APPEND _inc_env "${_path_env}")
    string(REPLACE ":" ";" _path_env "$ENV{CPATH}")
    list(APPEND _inc_env "${_path_env}")
    string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}")
    list(APPEND _inc_env "${_path_env}")
  endif()
  list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}")
  list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}")
  set(ENV_MKLROOT "$ENV{MKLROOT}")
  if (ENV_MKLROOT)
    list(APPEND _inc_env "${ENV_MKLROOT}/include")
  endif()
  list(REMOVE_DUPLICATES _inc_env)
162

PRUVOST Florent's avatar
PRUVOST Florent committed
163 164 165
  # find mkl.h inside known include paths
  set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
  if(BLAS_INCDIR)
166
    set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
PRUVOST Florent's avatar
PRUVOST Florent committed
167 168 169 170 171 172 173
    find_path(BLAS_mkl.h_INCLUDE_DIRS
      NAMES mkl.h
      HINTS ${BLAS_INCDIR})
  else()
    if(BLAS_DIR)
      set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
      find_path(BLAS_mkl.h_INCLUDE_DIRS
174 175 176
        NAMES mkl.h
        HINTS ${BLAS_DIR}
        PATH_SUFFIXES include)
177
    else()
PRUVOST Florent's avatar
PRUVOST Florent committed
178 179
      set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND")
      find_path(BLAS_mkl.h_INCLUDE_DIRS
180 181
        NAMES mkl.h
        HINTS ${_inc_env})
182
    endif()
PRUVOST Florent's avatar
PRUVOST Florent committed
183 184 185 186 187 188 189 190 191 192 193
  endif()
  mark_as_advanced(BLAS_mkl.h_INCLUDE_DIRS)
  ## Print status if not found
  ## -------------------------
  #if (NOT BLAS_mkl.h_INCLUDE_DIRS AND MORSE_VERBOSE)
  #    Print_Find_Header_Status(blas mkl.h)
  #endif ()
  set(BLAS_INCLUDE_DIRS "")
  if(BLAS_mkl.h_INCLUDE_DIRS)
    list(APPEND BLAS_INCLUDE_DIRS "${BLAS_mkl.h_INCLUDE_DIRS}" )
  endif()
194

PRUVOST Florent's avatar
PRUVOST Florent committed
195 196 197 198 199
  ###
  # look for libs
  ###
  # if Intel 10 64 bit -> look for sequential and multithreaded versions
  if(BLA_VENDOR MATCHES "Intel10_64lp*")
200 201

    ## look for the sequential version
PRUVOST Florent's avatar
PRUVOST Florent committed
202 203 204 205
    set(BLA_VENDOR "Intel10_64lp_seq")
    if(NOT BLASEXT_FIND_QUIETLY)
      message(STATUS "Look for the sequential version Intel10_64lp_seq")
    endif()
206
    find_package_blas(0)
207
    if(BLAS_FOUND)
PRUVOST Florent's avatar
PRUVOST Florent committed
208
      set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
209 210 211 212 213 214
      if (BLAS_COMPILER_FLAGS)
        set (BLAS_SEQ_COMPILER_FLAGS "${BLAS_COMPILER_FLAGS}")
      endif()
      if (BLAS_LINKER_FLAGS)
        set (BLAS_SEQ_LINKER_FLAGS "${BLAS_LINKER_FLAGS}")
      endif()
215
    else()
PRUVOST Florent's avatar
PRUVOST Florent committed
216
      set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
217 218 219
    endif()

    ## look for the multithreaded version
PRUVOST Florent's avatar
PRUVOST Florent committed
220 221 222 223
    set(BLA_VENDOR "Intel10_64lp")
    if(NOT BLASEXT_FIND_QUIETLY)
      message(STATUS "Look for the multithreaded version Intel10_64lp")
    endif()
224
    find_package_blas(0)
225
    if(BLAS_FOUND)
PRUVOST Florent's avatar
PRUVOST Florent committed
226
      set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
227 228 229 230 231 232
      if (BLAS_COMPILER_FLAGS)
        set (BLAS_PAR_COMPILER_FLAGS "${BLAS_COMPILER_FLAGS}")
      endif()
      if (BLAS_LINKER_FLAGS)
        set (BLAS_PAR_LINKER_FLAGS "${BLAS_LINKER_FLAGS}")
      endif()
233
    else()
PRUVOST Florent's avatar
PRUVOST Florent committed
234
      set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
235 236
    endif()

PRUVOST Florent's avatar
PRUVOST Florent committed
237
  else()
238 239

    if(BLAS_FOUND)
PRUVOST Florent's avatar
PRUVOST Florent committed
240
      set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
241
    else()
PRUVOST Florent's avatar
PRUVOST Florent committed
242
      set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
243 244
    endif()

PRUVOST Florent's avatar
PRUVOST Florent committed
245
  endif()
246

PRUVOST Florent's avatar
PRUVOST Florent committed
247 248
  # ACML case
elseif(BLA_VENDOR MATCHES "ACML*")
249

PRUVOST Florent's avatar
PRUVOST Florent committed
250 251
  ## look for the sequential version
  set(BLA_VENDOR "ACML")
252
  find_package_blas(0)
PRUVOST Florent's avatar
PRUVOST Florent committed
253 254 255 256 257 258 259 260
  if(BLAS_FOUND)
    set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
  else()
    set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
  endif()

  ## look for the multithreaded version
  set(BLA_VENDOR "ACML_MP")
261
  find_package_blas(0)
PRUVOST Florent's avatar
PRUVOST Florent committed
262 263 264
  if(BLAS_FOUND)
    set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
  else()
265
    set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
PRUVOST Florent's avatar
PRUVOST Florent committed
266 267 268 269 270 271 272
  endif()

  # IBMESSL case
elseif(BLA_VENDOR MATCHES "IBMESSL*")

  ## look for the sequential version
  set(BLA_VENDOR "IBMESSL")
273
  find_package_blas(0)
PRUVOST Florent's avatar
PRUVOST Florent committed
274 275 276 277 278 279 280 281
  if(BLAS_FOUND)
    set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
  else()
    set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
  endif()

  ## look for the multithreaded version
  set(BLA_VENDOR "IBMESSLMT")
282
  find_package_blas(0)
PRUVOST Florent's avatar
PRUVOST Florent committed
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
  if(BLAS_FOUND)
    set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}")
  else()
    set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
  endif()

else()

  if(BLAS_FOUND)
    # define the SEQ libs as the BLAS_LIBRARIES
    set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}")
  else()
    set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}")
  endif()
  set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}")
298 299 300

endif()

301
# Reset pure BLAS cmake variables to the sequential case (arbitrary default)
302
if(BLAS_SEQ_LIBRARIES)
PRUVOST Florent's avatar
PRUVOST Florent committed
303
  set(BLAS_LIBRARIES "${BLAS_SEQ_LIBRARIES}")
304 305
  set(BLAS_COMPILER_FLAGS "${BLAS_SEQ_COMPILER_FLAGS}")
  set(BLAS_LINKER_FLAGS "${BLAS_SEQ_LINKER_FLAGS}")
306 307 308 309 310
endif()

# extract libs paths
# remark: because it is not given by find_package(BLAS)
set(BLAS_LIBRARY_DIRS "")
311
string(REPLACE " " ";" BLAS_LIBRARIES "${BLAS_LIBRARIES}")
312
foreach(blas_lib ${BLAS_LIBRARIES})
PRUVOST Florent's avatar
PRUVOST Florent committed
313 314 315 316 317
  if (EXISTS "${blas_lib}")
    get_filename_component(a_blas_lib_dir "${blas_lib}" PATH)
    list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" )
  else()
    string(REPLACE "-L" "" blas_lib "${blas_lib}")
318
    if (EXISTS "${blas_lib}")
PRUVOST Florent's avatar
PRUVOST Florent committed
319
      list(APPEND BLAS_LIBRARY_DIRS "${blas_lib}" )
PRUVOST Florent's avatar
PRUVOST Florent committed
320
    else()
PRUVOST Florent's avatar
PRUVOST Florent committed
321 322
      get_filename_component(a_blas_lib_dir "${blas_lib}" PATH)
      if (EXISTS "${a_blas_lib_dir}")
323
        list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" )
PRUVOST Florent's avatar
PRUVOST Florent committed
324
      endif()
325
    endif()
PRUVOST Florent's avatar
PRUVOST Florent committed
326
  endif()
327 328
endforeach()
if (BLAS_LIBRARY_DIRS)
PRUVOST Florent's avatar
PRUVOST Florent committed
329
  list(REMOVE_DUPLICATES BLAS_LIBRARY_DIRS)
330 331
endif ()

332
# check that BLASEXT has been found
333 334 335
# ---------------------------------
include(FindPackageHandleStandardArgs)
if(BLA_VENDOR MATCHES "Intel*")
336 337 338 339 340 341 342 343 344
  if(NOT BLASEXT_FIND_QUIETLY)
    message(STATUS "BLAS found is Intel MKL")
    message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
  endif()
  find_package_handle_standard_args(BLASEXT DEFAULT_MSG
    BLAS_SEQ_LIBRARIES
    BLAS_LIBRARY_DIRS
    BLAS_INCLUDE_DIRS)
  if(BLA_VENDOR MATCHES "Intel10_64lp*" AND BLAS_PAR_LIBRARIES)
345
    if(NOT BLASEXT_FIND_QUIETLY)
346
      message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
347
    endif()
348 349
    find_package_handle_standard_args(BLASEXT DEFAULT_MSG
      BLAS_PAR_LIBRARIES)
PRUVOST Florent's avatar
PRUVOST Florent committed
350 351 352
  endif()
elseif(BLA_VENDOR MATCHES "ACML*")
  if(NOT BLASEXT_FIND_QUIETLY)
353
    message(STATUS "BLAS found is ACML")
PRUVOST Florent's avatar
PRUVOST Florent committed
354 355
    message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
  endif()
356
  find_package_handle_standard_args(BLASEXT DEFAULT_MSG
PRUVOST Florent's avatar
PRUVOST Florent committed
357 358 359 360 361
    BLAS_SEQ_LIBRARIES
    BLAS_LIBRARY_DIRS)
  if(BLAS_PAR_LIBRARIES)
    if(NOT BLASEXT_FIND_QUIETLY)
      message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
362
    endif()
363
    find_package_handle_standard_args(BLASEXT DEFAULT_MSG
PRUVOST Florent's avatar
PRUVOST Florent committed
364 365 366 367
      BLAS_PAR_LIBRARIES)
  endif()
elseif(BLA_VENDOR MATCHES "IBMESSL*")
  if(NOT BLASEXT_FIND_QUIETLY)
368
    message(STATUS "BLAS found is ESSL")
PRUVOST Florent's avatar
PRUVOST Florent committed
369 370
    message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
  endif()
371
  find_package_handle_standard_args(BLASEXT DEFAULT_MSG
PRUVOST Florent's avatar
PRUVOST Florent committed
372 373 374
    BLAS_SEQ_LIBRARIES
    BLAS_LIBRARY_DIRS)
  if(BLAS_PAR_LIBRARIES)
375
    if(NOT BLASEXT_FIND_QUIETLY)
PRUVOST Florent's avatar
PRUVOST Florent committed
376
      message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES")
377
    endif()
378
    find_package_handle_standard_args(BLASEXT DEFAULT_MSG
PRUVOST Florent's avatar
PRUVOST Florent committed
379 380 381 382 383 384
      BLAS_PAR_LIBRARIES)
  endif()
else()
  if(NOT BLASEXT_FIND_QUIETLY)
    message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES")
  endif()
385
  find_package_handle_standard_args(BLASEXT DEFAULT_MSG
PRUVOST Florent's avatar
PRUVOST Florent committed
386 387
    BLAS_SEQ_LIBRARIES
    BLAS_LIBRARY_DIRS)
388
endif()
389 390 391 392 393 394 395 396 397 398

if (BLAS_LIBRARIES)
  set(BLASEXT_LIBRARIES ${BLAS_LIBRARIES})
endif()
if (BLAS_INCLUDE_DIRS)
  set(BLASEXT_INCLUDE_DIRS ${BLAS_INCLUDE_DIRS})
endif()
if (BLAS_LIBRARY_DIRS)
  set(BLASEXT_LIBRARY_DIRS ${BLAS_LIBRARY_DIRS})
endif()