2 # This module finds an installed fortran library that implements the BLAS
3 # linear-algebra interface (see http://www.netlib.org/blas/).
4 # The list of libraries searched for is taken
5 # from the autoconf macro file, acx_blas.m4 (distributed at
6 # http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
8 # This module sets the following variables:
9 # BLAS_FOUND - set to true if a library implementing the BLAS interface
11 # BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l
13 # BLAS_LIBRARIES - uncached list of libraries (using full path name) to
14 # link against to use BLAS
15 # BLAS95_LIBRARIES - uncached list of libraries (using full path name)
16 # to link against to use BLAS95 interface
17 # BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface
19 # BLA_STATIC if set on this determines what kind of linkage we do (static)
20 # BLA_VENDOR if set checks only the specified vendor, if not set checks
21 # all the possibilities
22 # BLA_F95 if set on tries to find the f95 interfaces for BLAS/LAPACK
24 ### List of vendors (BLA_VENDOR) valid in this module
25 ## Goto,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model),
26 ## Intel10_64lp_seq (intel mkl v10 64 bit,sequential code, lp64 model),
27 ## Intel( older versions of mkl 32 and 64 bit), ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic
28 # C/CXX should be enabled to use Intel mkl
30 #=============================================================================
31 # Copyright 2007-2009 Kitware, Inc.
33 # Distributed under the OSI-approved BSD License (the "License");
34 # see accompanying file Copyright.txt for details.
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 CMake, substitute the full
41 # License text for the above reference.)
43 include(CheckFunctionExists)
44 include(CheckFortranFunctionExists)
45 include(CheckTypeSize)
47 set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
49 # Check the language being used
50 get_property( _LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES )
51 if( _LANGUAGES_ MATCHES Fortran )
52 set( _CHECK_FORTRAN TRUE )
53 elseif( (_LANGUAGES_ MATCHES C) OR (_LANGUAGES_ MATCHES CXX) )
54 set( _CHECK_FORTRAN FALSE )
56 if(BLAS_FIND_REQUIRED)
57 message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
58 else(BLAS_FIND_REQUIRED)
59 message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)")
61 endif(BLAS_FIND_REQUIRED)
64 macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
65 # This macro checks for the existence of the combination of fortran libraries
66 # given by _list. If the combination is found, this macro checks (using the
67 # Check_Fortran_Function_Exists macro) whether can link against that library
68 # combination using the name of a routine given by _name using the linker
69 # flags given by _flags. If the combination of libraries is found and passes
70 # the link test, LIBRARIES is set to the list of complete library paths that
71 # have been found. Otherwise, LIBRARIES is set to FALSE.
73 # N.B. _prefix is the prefix applied to the names of all cached variables that
74 # are generated internally and marked advanced by this macro.
78 set(_libraries_work TRUE)
85 set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH)
87 set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH)
91 foreach(_library ${_list})
92 set(_combined_name ${_combined_name}_${_library})
97 set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
100 set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
102 set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
105 if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
106 # for ubuntu's libblas3gf and liblapack3gf packages
107 set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
110 find_library(${_prefix}_${_library}_LIBRARY
114 mark_as_advanced(${_prefix}_${_library}_LIBRARY)
115 set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
116 set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
117 endif(_libraries_work)
118 endforeach(_library ${_list})
120 # Test this combination of libraries.
121 set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_thread})
122 # message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
124 check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
126 check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
128 set(CMAKE_REQUIRED_LIBRARIES)
129 mark_as_advanced(${_prefix}${_combined_name}_WORKS)
130 set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
131 endif(_libraries_work)
132 if(NOT _libraries_work)
133 set(${LIBRARIES} FALSE)
134 endif(NOT _libraries_work)
135 #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
136 endmacro(Check_Fortran_Libraries)
138 set(BLAS_LINKER_FLAGS)
140 set(BLAS95_LIBRARIES)
141 if ($ENV{BLA_VENDOR} MATCHES ".+")
142 set(BLA_VENDOR $ENV{BLA_VENDOR})
143 else ($ENV{BLA_VENDOR} MATCHES ".+")
145 set(BLA_VENDOR "All")
146 endif(NOT BLA_VENDOR)
147 endif ($ENV{BLA_VENDOR} MATCHES ".+")
149 if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
150 if(NOT BLAS_LIBRARIES)
151 # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
152 check_fortran_libraries(
160 endif(NOT BLAS_LIBRARIES)
161 endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
163 if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
164 if(NOT BLAS_LIBRARIES)
165 # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
166 check_fortran_libraries(
174 endif(NOT BLAS_LIBRARIES)
175 endif (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
177 # BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
178 if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
179 if(NOT BLAS_LIBRARIES)
180 check_fortran_libraries(
188 endif(NOT BLAS_LIBRARIES)
189 endif (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
191 # BLAS in Alpha CXML library?
192 if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
193 if(NOT BLAS_LIBRARIES)
194 check_fortran_libraries(
202 endif(NOT BLAS_LIBRARIES)
203 endif (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
205 # BLAS in Alpha DXML library? (now called CXML, see above)
206 if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
207 if(NOT BLAS_LIBRARIES)
208 check_fortran_libraries(
216 endif(NOT BLAS_LIBRARIES)
217 endif (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
219 # BLAS in Sun Performance library?
220 if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
221 if(NOT BLAS_LIBRARIES)
222 check_fortran_libraries(
231 set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
232 endif(BLAS_LIBRARIES)
233 endif(NOT BLAS_LIBRARIES)
234 endif (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
236 # BLAS in SCSL library? (SGI/Cray Scientific Library)
237 if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
238 if(NOT BLAS_LIBRARIES)
239 check_fortran_libraries(
247 endif(NOT BLAS_LIBRARIES)
248 endif (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
250 # BLAS in SGIMATH library?
251 if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
252 if(NOT BLAS_LIBRARIES)
253 check_fortran_libraries(
261 endif(NOT BLAS_LIBRARIES)
262 endif (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
264 # BLAS in IBM ESSL library? (requires generic BLAS lib, too)
265 if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
266 if(NOT BLAS_LIBRARIES)
267 check_fortran_libraries(
275 endif(NOT BLAS_LIBRARIES)
276 endif (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
278 #BLAS in acml library?
279 if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All")
280 if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
281 ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
282 ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))
284 # try to find acml in "standard" paths
286 file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" )
288 file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" )
291 file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" )
293 file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" )
295 list(GET _ACML_ROOT 0 _ACML_ROOT)
296 list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
298 get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH )
299 check_type_size("int" SIZEOF_INTEGER)
300 if( SIZEOF_INTEGER EQUAL 8 )
301 set( _ACML_PATH_SUFFIX "_int64" )
303 set( _ACML_PATH_SUFFIX "" )
305 if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" )
306 set( _ACML_COMPILER32 "ifort32" )
307 set( _ACML_COMPILER64 "ifort64" )
308 elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" )
309 set( _ACML_COMPILER32 "sun32" )
310 set( _ACML_COMPILER64 "sun64" )
311 elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" )
312 set( _ACML_COMPILER32 "pgi32" )
314 set( _ACML_COMPILER64 "win64" )
316 set( _ACML_COMPILER64 "pgi64" )
318 elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" )
319 # 32 bit builds not supported on Open64 but for code simplicity
320 # We'll just use the same directory twice
321 set( _ACML_COMPILER32 "open64_64" )
322 set( _ACML_COMPILER64 "open64_64" )
323 elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" )
324 set( _ACML_COMPILER32 "nag32" )
325 set( _ACML_COMPILER64 "nag64" )
326 else() #if( CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" )
327 set( _ACML_COMPILER32 "gfortran32" )
328 set( _ACML_COMPILER64 "gfortran64" )
331 if( BLA_VENDOR STREQUAL "ACML_MP" )
332 set(_ACML_MP_LIB_DIRS
333 "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
334 "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" )
335 else() #if( _BLAS_VENDOR STREQUAL "ACML" )
337 "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
338 "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" )
341 elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
342 set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
345 if( BLA_VENDOR STREQUAL "ACML_MP" )
346 foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
347 check_fortran_libraries (
351 "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS}
357 elseif( BLA_VENDOR STREQUAL "ACML_GPU" )
358 foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
359 check_fortran_libraries (
363 "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS}
369 else() #if( _BLAS_VENDOR STREQUAL "ACML" )
370 foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} )
371 check_fortran_libraries (
375 "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS}
383 # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
384 if(NOT BLAS_LIBRARIES)
385 check_fortran_libraries(
393 endif(NOT BLAS_LIBRARIES)
394 if(NOT BLAS_LIBRARIES)
395 check_fortran_libraries(
403 endif(NOT BLAS_LIBRARIES)
404 if(NOT BLAS_LIBRARIES)
405 check_fortran_libraries(
410 "acml;acml_mv;CALBLAS"
413 endif(NOT BLAS_LIBRARIES)
416 # Apple BLAS library?
417 if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
418 if(NOT BLAS_LIBRARIES)
419 check_fortran_libraries(
427 endif(NOT BLAS_LIBRARIES)
428 endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
430 if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
431 if ( NOT BLAS_LIBRARIES )
432 check_fortran_libraries(
440 endif ( NOT BLAS_LIBRARIES )
441 endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
442 # Generic BLAS library?
443 if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
444 if(NOT BLAS_LIBRARIES)
445 check_fortran_libraries(
453 endif(NOT BLAS_LIBRARIES)
454 endif (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
456 #BLAS in intel mkl 10 library? (em64t 64bit)
457 if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
461 if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
462 if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
463 find_package(Threads)
464 else(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
465 find_package(Threads REQUIRED)
466 endif(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
468 set(BLAS_SEARCH_LIBS "")
471 set(BLAS_mkl_SEARCH_SYMBOL SGEMM)
472 set(_LIBRARIES BLAS95_LIBRARIES)
474 list(APPEND BLAS_SEARCH_LIBS
475 "mkl_blas95 mkl_intel_c mkl_intel_thread mkl_core libguide40")
477 if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
478 list(APPEND BLAS_SEARCH_LIBS
479 "mkl_blas95 mkl_intel mkl_intel_thread mkl_core guide")
481 if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
483 list(APPEND BLAS_SEARCH_LIBS
484 "mkl_blas95 mkl_intel_lp64 mkl_intel_thread mkl_core guide")
487 if (CMAKE_C_COMPILER MATCHES ".+gcc.*")
488 list(APPEND BLAS_SEARCH_LIBS
489 "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core")
490 set(LM "${LM};-lgomp")
492 list(APPEND BLAS_SEARCH_LIBS
493 "mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core iomp5")
497 if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
498 list(APPEND BLAS_SEARCH_LIBS
499 "mkl_blas95_lp64 mkl_intel_lp64 mkl_sequential mkl_core")
502 set(BLAS_mkl_SEARCH_SYMBOL sgemm)
503 set(_LIBRARIES BLAS_LIBRARIES)
505 list(APPEND BLAS_SEARCH_LIBS
506 "mkl_c_dll mkl_intel_thread_dll mkl_core_dll libguide40")
508 if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
509 list(APPEND BLAS_SEARCH_LIBS
510 "mkl_intel mkl_intel_thread mkl_core guide")
512 if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
515 list(APPEND BLAS_SEARCH_LIBS
516 "mkl_intel_lp64 mkl_intel_thread mkl_core guide")
519 if (CMAKE_C_COMPILER MATCHES ".+gcc.*")
520 list(APPEND BLAS_SEARCH_LIBS
521 "mkl_intel_lp64 mkl_gnu_thread mkl_core")
522 set(LM "${LM};-lgomp")
524 list(APPEND BLAS_SEARCH_LIBS
525 "mkl_intel_lp64 mkl_intel_thread mkl_core iomp5")
529 #older vesions of intel mkl libs
530 if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
531 list(APPEND BLAS_SEARCH_LIBS
533 list(APPEND BLAS_SEARCH_LIBS
535 list(APPEND BLAS_SEARCH_LIBS
539 if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All")
540 list(APPEND BLAS_SEARCH_LIBS
541 "mkl_intel_lp64 mkl_sequential mkl_core")
545 foreach (IT ${BLAS_SEARCH_LIBS})
546 string(REPLACE " " ";" SEARCH_LIBS ${IT})
549 check_fortran_libraries(
552 ${BLAS_mkl_SEARCH_SYMBOL}
555 "${CMAKE_THREAD_LIBS_INIT};${LM}"
560 endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
561 endif (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
566 set(BLAS95_FOUND TRUE)
567 else(BLAS95_LIBRARIES)
568 set(BLAS95_FOUND FALSE)
569 endif(BLAS95_LIBRARIES)
571 if(NOT BLAS_FIND_QUIETLY)
573 message(STATUS "A library with BLAS95 API found.")
575 if(BLAS_FIND_REQUIRED)
577 "A required library with BLAS95 API not found. Please specify library location.")
578 else(BLAS_FIND_REQUIRED)
580 "A library with BLAS95 API not found. Please specify library location.")
581 endif(BLAS_FIND_REQUIRED)
583 endif(NOT BLAS_FIND_QUIETLY)
585 set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}")
590 set(BLAS_FOUND FALSE)
591 endif(BLAS_LIBRARIES)
593 if(NOT BLAS_FIND_QUIETLY)
595 message(STATUS "A library with BLAS API found.")
597 if(BLAS_FIND_REQUIRED)
599 "A required library with BLAS API not found. Please specify library location."
601 else(BLAS_FIND_REQUIRED)
603 "A library with BLAS API not found. Please specify library location."
605 endif(BLAS_FIND_REQUIRED)
607 endif(NOT BLAS_FIND_QUIETLY)
610 set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})