1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5FindLAPACK
6----------
7
8Find Linear Algebra PACKage (LAPACK) library
9
10This module finds an installed Fortran library that implements the
11`LAPACK linear-algebra interface`_.
12
13At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled.
14
15.. _`LAPACK linear-algebra interface`: http://www.netlib.org/lapack/
16
17Input Variables
18^^^^^^^^^^^^^^^
19
20The following variables may be set to influence this module's behavior:
21
22``BLA_STATIC``
23  if ``ON`` use static linkage
24
25``BLA_VENDOR``
26  Set to one of the :ref:`BLAS/LAPACK Vendors` to search for BLAS only
27  from the specified vendor.  If not set, all vendors are considered.
28
29``BLA_F95``
30  if ``ON`` tries to find the BLAS95/LAPACK95 interfaces
31
32``BLA_PREFER_PKGCONFIG``
33  .. versionadded:: 3.20
34
35  if set ``pkg-config`` will be used to search for a LAPACK library first
36  and if one is found that is preferred
37
38``BLA_SIZEOF_INTEGER``
39  .. versionadded:: 3.22
40
41  Specify the BLAS/LAPACK library integer size:
42
43  ``4``
44    Search for a BLAS/LAPACK with 32-bit integer interfaces.
45  ``8``
46    Search for a BLAS/LAPACK with 64-bit integer interfaces.
47  ``ANY``
48    Search for any BLAS/LAPACK.
49    Most likely, a BLAS/LAPACK with 32-bit integer interfaces will be found.
50
51Imported targets
52^^^^^^^^^^^^^^^^
53
54This module defines the following :prop_tgt:`IMPORTED` targets:
55
56``LAPACK::LAPACK``
57  .. versionadded:: 3.18
58
59  The libraries to use for LAPACK, if found.
60
61Result Variables
62^^^^^^^^^^^^^^^^
63
64This module defines the following variables:
65
66``LAPACK_FOUND``
67  library implementing the LAPACK interface is found
68``LAPACK_LINKER_FLAGS``
69  uncached list of required linker flags (excluding ``-l`` and ``-L``).
70``LAPACK_LIBRARIES``
71  uncached list of libraries (using full path name) to link against
72  to use LAPACK
73``LAPACK95_LIBRARIES``
74  uncached list of libraries (using full path name) to link against
75  to use LAPACK95
76``LAPACK95_FOUND``
77  library implementing the LAPACK95 interface is found
78
79Intel MKL
80^^^^^^^^^
81
82To use the Intel MKL implementation of LAPACK, a project must enable at least
83one of the ``C`` or ``CXX`` languages.  Set ``BLA_VENDOR`` to an Intel MKL
84variant either on the command-line as ``-DBLA_VENDOR=Intel10_64lp`` or in
85project code:
86
87.. code-block:: cmake
88
89  set(BLA_VENDOR Intel10_64lp)
90  find_package(LAPACK)
91
92In order to build a project using Intel MKL, and end user must first
93establish an Intel MKL environment.  See the :module:`FindBLAS` module
94section on :ref:`Intel MKL` for details.
95
96#]=======================================================================]
97
98# The approach follows that of the ``autoconf`` macro file, ``acx_lapack.m4``
99# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
100
101if(CMAKE_Fortran_COMPILER_LOADED)
102  include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
103else()
104  include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
105endif()
106include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
107
108function(_add_lapack_target)
109  if(LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK)
110    add_library(LAPACK::LAPACK INTERFACE IMPORTED)
111
112    # Filter out redundant BLAS info and replace with the BLAS target
113    set(_lapack_libs "${LAPACK_LIBRARIES}")
114    set(_lapack_flags "${LAPACK_LINKER_FLAGS}")
115    if(TARGET BLAS::BLAS)
116      if(_lapack_libs AND BLAS_LIBRARIES)
117        foreach(_blas_lib IN LISTS BLAS_LIBRARIES)
118          list(REMOVE_ITEM _lapack_libs "${_blas_lib}")
119        endforeach()
120      endif()
121      if(_lapack_flags AND BLAS_LINKER_FLAGS)
122        foreach(_blas_flag IN LISTS BLAS_LINKER_FLAGS)
123          list(REMOVE_ITEM _lapack_flags "${_blas_flag}")
124        endforeach()
125      endif()
126      list(APPEND _lapack_libs BLAS::BLAS)
127    endif()
128    if(_lapack_libs)
129      set_target_properties(LAPACK::LAPACK PROPERTIES
130        INTERFACE_LINK_LIBRARIES "${_lapack_libs}"
131      )
132    endif()
133    if(_lapack_flags)
134      set_target_properties(LAPACK::LAPACK PROPERTIES
135        INTERFACE_LINK_OPTIONS "${_lapack_flags}"
136      )
137    endif()
138  endif()
139endfunction()
140
141# TODO: move this stuff to a separate module
142
143function(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _deps _addlibdir _subdirs _blas)
144  # This function checks for the existence of the combination of libraries
145  # given by _list.  If the combination is found, this checks whether can link
146  # against that library combination using the name of a routine given by _name
147  # using the linker flags given by _flags.  If the combination of libraries is
148  # found and passes the link test, ${LIBRARIES} is set to the list of complete
149  # library paths that have been found.  Otherwise, ${LIBRARIES} is set to FALSE.
150
151  set(_libraries_work TRUE)
152  set(_libraries)
153  set(_combined_name)
154
155  if(BLA_STATIC)
156    if(WIN32)
157      set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
158    else()
159      set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
160    endif()
161  else()
162    if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
163      # for ubuntu's libblas3gf and liblapack3gf packages
164      set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
165    endif()
166  endif()
167
168  set(_extaddlibdir "${_addlibdir}")
169  if(WIN32)
170    list(APPEND _extaddlibdir ENV LIB)
171  elseif(APPLE)
172    list(APPEND _extaddlibdir ENV DYLD_LIBRARY_PATH)
173  else()
174    list(APPEND _extaddlibdir ENV LD_LIBRARY_PATH)
175  endif()
176  list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
177
178  foreach(_library ${_list})
179    if(_library MATCHES "^-")
180      # Respect linker flags as-is (required by MKL)
181      list(APPEND _libraries "${_library}")
182    else()
183      string(REGEX REPLACE "[^A-Za-z0-9]" "_" _lib_var "${_library}")
184      string(APPEND _combined_name "_${_lib_var}")
185      if(NOT "${_deps}" STREQUAL "")
186        string(APPEND _combined_name "_deps")
187      endif()
188      if(_libraries_work)
189        find_library(${_prefix}_${_lib_var}_LIBRARY
190          NAMES ${_library}
191          NAMES_PER_DIR
192          PATHS ${_extaddlibdir}
193          PATH_SUFFIXES ${_subdirs}
194        )
195        mark_as_advanced(${_prefix}_${_lib_var}_LIBRARY)
196        list(APPEND _libraries ${${_prefix}_${_lib_var}_LIBRARY})
197        set(_libraries_work ${${_prefix}_${_lib_var}_LIBRARY})
198      endif()
199    endif()
200  endforeach()
201
202  foreach(_flag ${_flags})
203    string(REGEX REPLACE "[^A-Za-z0-9]" "_" _flag_var "${_flag}")
204    string(APPEND _combined_name "_${_flag_var}")
205  endforeach()
206  if(_libraries_work)
207    # Test this combination of libraries.
208    set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${_libraries} ${_blas} ${_deps})
209    set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY})
210    if(CMAKE_Fortran_COMPILER_LOADED)
211      check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
212    else()
213      check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
214    endif()
215    set(CMAKE_REQUIRED_LIBRARIES)
216    set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
217  endif()
218
219  if(_libraries_work)
220    if("${_list}${_blas}" STREQUAL "")
221      set(_libraries "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
222    else()
223      list(APPEND _libraries ${_blas} ${_deps})
224    endif()
225  else()
226    set(_libraries FALSE)
227  endif()
228  set(${LIBRARIES} "${_libraries}" PARENT_SCOPE)
229endfunction()
230
231macro(_lapack_find_dependency dep)
232  set(_lapack_quiet_arg)
233  if(LAPACK_FIND_QUIETLY)
234    set(_lapack_quiet_arg QUIET)
235  endif()
236  set(_lapack_required_arg)
237  if(LAPACK_FIND_REQUIRED)
238    set(_lapack_required_arg REQUIRED)
239  endif()
240  find_package(${dep} ${ARGN}
241    ${_lapack_quiet_arg}
242    ${_lapack_required_arg}
243  )
244  if (NOT ${dep}_FOUND)
245    set(LAPACK_NOT_FOUND_MESSAGE "LAPACK could not be found because dependency ${dep} could not be found.")
246  endif()
247
248  set(_lapack_required_arg)
249  set(_lapack_quiet_arg)
250endmacro()
251
252set(LAPACK_LINKER_FLAGS)
253set(LAPACK_LIBRARIES)
254set(LAPACK95_LIBRARIES)
255set(_lapack_fphsa_req_var LAPACK_LIBRARIES)
256
257# Check the language being used
258if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
259  set(LAPACK_NOT_FOUND_MESSAGE
260    "FindLAPACK requires Fortran, C, or C++ to be enabled.")
261endif()
262
263if(NOT BLA_SIZEOF_INTEGER)
264  # in the reality we do not know which API of BLAS/LAPACK is masked in library
265  set(_lapack_sizeof_integer "ANY")
266elseif((BLA_SIZEOF_INTEGER STREQUAL "ANY") OR
267       (BLA_SIZEOF_INTEGER STREQUAL "4") OR
268       (BLA_SIZEOF_INTEGER STREQUAL "8"))
269  set(_lapack_sizeof_integer ${BLA_SIZEOF_INTEGER})
270else()
271  message(FATAL_ERROR "BLA_SIZEOF_INTEGER can have only <no value>, ANY, 4, or 8 values")
272endif()
273
274# Load BLAS
275if(NOT LAPACK_NOT_FOUND_MESSAGE)
276  _lapack_find_dependency(BLAS)
277endif()
278
279# Search with pkg-config if specified
280if(BLA_PREFER_PKGCONFIG)
281  find_package(PkgConfig)
282  pkg_check_modules(PKGC_LAPACK lapack)
283  if(PKGC_LAPACK_FOUND)
284    set(LAPACK_FOUND TRUE)
285    set(LAPACK_LIBRARIES "${PKGC_LAPACK_LINK_LIBRARIES}")
286    if (BLAS_LIBRARIES)
287      list(APPEND LAPACK_LIBRARIES "${BLAS_LIBRARIES}")
288    endif()
289    _add_lapack_target()
290    return()
291  endif()
292endif()
293
294# Search for different LAPACK distributions if BLAS is found
295if(NOT LAPACK_NOT_FOUND_MESSAGE)
296  set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
297  if(NOT $ENV{BLA_VENDOR} STREQUAL "")
298    set(BLA_VENDOR $ENV{BLA_VENDOR})
299  elseif(NOT BLA_VENDOR)
300    set(BLA_VENDOR "All")
301  endif()
302
303  # LAPACK in the Intel MKL 10+ library?
304  if(NOT LAPACK_LIBRARIES
305      AND (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
306      AND (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED))
307    # System-specific settings
308    if(NOT WIN32)
309      set(LAPACK_mkl_LM "-lm")
310      set(LAPACK_mkl_LDL "-ldl")
311    endif()
312
313    _lapack_find_dependency(Threads)
314
315    if(_lapack_sizeof_integer EQUAL 8)
316      set(LAPACK_mkl_ILP_MODE "ilp64")
317    elseif(_lapack_sizeof_integer EQUAL 4)
318      set(LAPACK_mkl_ILP_MODE "lp64")
319    else()
320      if(BLA_VENDOR MATCHES "_64ilp")
321        set(LAPACK_mkl_ILP_MODE "ilp64")
322      else()
323        set(LAPACK_mkl_ILP_MODE "lp64")
324      endif()
325    endif()
326
327    set(LAPACK_SEARCH_LIBS "")
328
329    if(BLA_F95)
330      set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95")
331      set(_LAPACK_LIBRARIES LAPACK95_LIBRARIES)
332      set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
333
334      # old
335      list(APPEND LAPACK_SEARCH_LIBS
336        "mkl_lapack95")
337      # new >= 10.3
338      list(APPEND LAPACK_SEARCH_LIBS
339        "mkl_intel_c")
340      list(APPEND LAPACK_SEARCH_LIBS
341        "mkl_lapack95_${LAPACK_mkl_ILP_MODE}")
342    else()
343      set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
344      set(_LAPACK_LIBRARIES LAPACK_LIBRARIES)
345      set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
346
347      # old and new >= 10.3
348      list(APPEND LAPACK_SEARCH_LIBS
349        "mkl_lapack")
350    endif()
351
352    # MKL uses a multitude of partially platform-specific subdirectories:
353    if(BLA_VENDOR STREQUAL "Intel10_32")
354      set(LAPACK_mkl_ARCH_NAME "ia32")
355    else()
356      set(LAPACK_mkl_ARCH_NAME "intel64")
357    endif()
358    if(WIN32)
359      set(LAPACK_mkl_OS_NAME "win")
360    elseif(APPLE)
361      set(LAPACK_mkl_OS_NAME "mac")
362    else()
363      set(LAPACK_mkl_OS_NAME "lin")
364    endif()
365    if(DEFINED ENV{MKLROOT})
366      file(TO_CMAKE_PATH "$ENV{MKLROOT}" LAPACK_mkl_MKLROOT)
367      # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
368      # so we can better detect other relevant libraries in 'compiler' or 'tbb':
369      get_filename_component(LAPACK_mkl_MKLROOT_LAST_DIR "${LAPACK_mkl_MKLROOT}" NAME)
370      if(LAPACK_mkl_MKLROOT_LAST_DIR STREQUAL "mkl")
371          get_filename_component(LAPACK_mkl_MKLROOT "${LAPACK_mkl_MKLROOT}" DIRECTORY)
372      endif()
373    endif()
374    set(LAPACK_mkl_LIB_PATH_SUFFIXES
375        "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
376        "compiler/lib/${LAPACK_mkl_ARCH_NAME}"
377        "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
378        "mkl/lib/${LAPACK_mkl_ARCH_NAME}"
379        "lib" "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
380        "lib/${LAPACK_mkl_ARCH_NAME}"
381        )
382
383    # First try empty lapack libs (implicitly linked or automatic from BLAS)
384    if(NOT ${_LAPACK_LIBRARIES})
385      check_lapack_libraries(
386        ${_LAPACK_LIBRARIES}
387        LAPACK
388        ${LAPACK_mkl_SEARCH_SYMBOL}
389        ""
390        ""
391        "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
392        "${LAPACK_mkl_MKLROOT}"
393        "${LAPACK_mkl_LIB_PATH_SUFFIXES}"
394        "${_BLAS_LIBRARIES}"
395      )
396      if(LAPACK_WORKS AND NOT _BLAS_LIBRARIES)
397        # Give a more helpful "found" message
398        set(LAPACK_WORKS "implicitly linked")
399        set(_lapack_fphsa_req_var LAPACK_WORKS)
400      endif()
401    endif()
402
403    # Then try the search libs
404    foreach(_search ${LAPACK_SEARCH_LIBS})
405      string(REPLACE " " ";" _search ${_search})
406      if(NOT ${_LAPACK_LIBRARIES})
407        check_lapack_libraries(
408          ${_LAPACK_LIBRARIES}
409          LAPACK
410          ${LAPACK_mkl_SEARCH_SYMBOL}
411          ""
412          "${_search}"
413          "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
414          "${LAPACK_mkl_MKLROOT}"
415          "${LAPACK_mkl_LIB_PATH_SUFFIXES}"
416          "${_BLAS_LIBRARIES}"
417        )
418      endif()
419    endforeach()
420
421    unset(_search)
422    unset(LAPACK_mkl_ILP_MODE)
423    unset(LAPACK_mkl_SEARCH_SYMBOL)
424    unset(LAPACK_mkl_LM)
425    unset(LAPACK_mkl_LDL)
426    unset(LAPACK_mkl_MKLROOT)
427    unset(LAPACK_mkl_ARCH_NAME)
428    unset(LAPACK_mkl_OS_NAME)
429    unset(LAPACK_mkl_LIB_PATH_SUFFIXES)
430  endif()
431
432  # gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
433  if(NOT LAPACK_LIBRARIES
434      AND (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All"))
435    check_lapack_libraries(
436      LAPACK_LIBRARIES
437      LAPACK
438      cheev
439      ""
440      "goto2"
441      ""
442      ""
443      ""
444      "${BLAS_LIBRARIES}"
445    )
446  endif()
447
448  # FlexiBLAS? (http://www.mpi-magdeburg.mpg.de/mpcsc/software/FlexiBLAS/)
449  if(NOT LAPACK_LIBRARIES
450      AND (BLA_VENDOR STREQUAL "FlexiBLAS" OR BLA_VENDOR STREQUAL "All"))
451    set(_lapack_flexiblas_lib "flexiblas")
452
453    if(_lapack_sizeof_integer EQUAL 8)
454      string(APPEND _lapack_flexiblas_lib "64")
455    endif()
456
457    check_lapack_libraries(
458      LAPACK_LIBRARIES
459      LAPACK
460      cheev
461      ""
462      "${_lapack_flexiblas_lib}"
463      ""
464      ""
465      ""
466      "${BLAS_LIBRARIES}"
467    )
468
469    unset(_lapack_flexiblas_lib)
470  endif()
471
472  # OpenBLAS? (http://www.openblas.net)
473  if(NOT LAPACK_LIBRARIES
474      AND (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All"))
475    set(_lapack_openblas_lib "openblas")
476
477    if(_lapack_sizeof_integer EQUAL 8)
478      string(APPEND _lapack_openblas_lib "64")
479    endif()
480
481    check_lapack_libraries(
482      LAPACK_LIBRARIES
483      LAPACK
484      cheev
485      ""
486      "${_lapack_openblas_lib}"
487      ""
488      ""
489      ""
490      "${BLAS_LIBRARIES}"
491    )
492
493    unset(_lapack_openblas_lib)
494  endif()
495
496  # ArmPL? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
497  if(NOT LAPACK_LIBRARIES
498      AND (BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All"))
499    # Check for 64bit Integer support
500    if(_lapack_sizeof_integer EQUAL 8)
501      set(LAPACK_armpl_LIB "armpl_ilp64")
502    elseif(_lapack_sizeof_integer EQUAL 4)
503      set(LAPACK_armpl_LIB "armpl_lp64")
504    else()
505      if(BLA_VENDOR MATCHES "_ilp64")
506        set(LAPACK_armpl_LIB "armpl_ilp64")
507      else()
508        set(LAPACK_armpl_LIB "armpl_lp64")
509      endif()
510    endif()
511
512    # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
513    if(BLA_VENDOR MATCHES "_mp")
514      string(APPEND LAPACK_armpl_LIB "_mp")
515    endif()
516
517    check_lapack_libraries(
518      LAPACK_LIBRARIES
519      LAPACK
520      cheev
521      ""
522      "${LAPACK_armpl_LIB}"
523      ""
524      ""
525      ""
526      "${BLAS_LIBRARIES}"
527    )
528  endif()
529
530  # FLAME's blis library? (https://github.com/flame/blis)
531  if(NOT LAPACK_LIBRARIES
532      AND (BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All"))
533    if(_lapack_sizeof_integer EQUAL 8)
534      if(BLA_VENDOR STREQUAL "FLAME")
535        message(FATAL_ERROR "libFLAME does not support Int64 type")
536      endif()
537    else()
538      check_lapack_libraries(
539        LAPACK_LIBRARIES
540        LAPACK
541        cheev
542        ""
543        "flame"
544        ""
545        ""
546        ""
547        "${BLAS_LIBRARIES}"
548      )
549    endif()
550  endif()
551
552  # LAPACK in SCSL library? (SGI/Cray Scientific Library)
553  if(NOT LAPACK_LIBRARIES
554      AND (BLA_VENDOR MATCHES "SCSL" OR BLA_VENDOR STREQUAL "All"))
555    set(_lapack_scsl_lib "scs")
556
557    if(_lapack_sizeof_integer EQUAL 8)
558      string(APPEND _lapack_scsl_lib "_i8")
559    endif()
560    # Check for OpenMP support, VIA BLA_VENDOR of scs_mp
561    if(BLA_VENDOR MATCHES "_mp")
562      string(APPEND _lapack_scsl_lib "_mp")
563    endif()
564
565    check_lapack_libraries(
566      LAPACK_LIBRARIES
567      LAPACK
568      cheev
569      ""
570      "${_lapack_scsl_lib}"
571      ""
572      ""
573      ""
574      "${BLAS_LIBRARIES}"
575    )
576    unset(_lapack_scsl_lib)
577  endif()
578
579  # BLAS in acml library?
580  if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
581    if(BLAS_LIBRARIES MATCHES ".+acml.+")
582      set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
583    endif()
584  endif()
585
586  # Apple LAPACK library?
587  if(NOT LAPACK_LIBRARIES
588      AND (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All"))
589    if(_lapack_sizeof_integer EQUAL 8)
590      if(BLA_VENDOR STREQUAL "Apple")
591        message(FATAL_ERROR "Accelerate Framework does not support Int64 type")
592      endif()
593    else()
594      check_lapack_libraries(
595        LAPACK_LIBRARIES
596        LAPACK
597        cheev
598        ""
599        "Accelerate"
600        ""
601        ""
602        ""
603        "${BLAS_LIBRARIES}"
604      )
605    endif()
606  endif()
607
608  # Apple NAS (vecLib) library?
609  if(NOT LAPACK_LIBRARIES
610      AND (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All"))
611    if(_lapack_sizeof_integer EQUAL 8)
612      if(BLA_VENDOR STREQUAL "NAS")
613        message(FATAL_ERROR "Accelerate Framework does not support Int64 type")
614      endif()
615    else()
616      check_lapack_libraries(
617        LAPACK_LIBRARIES
618        LAPACK
619        cheev
620        ""
621        "vecLib"
622        ""
623        ""
624        ""
625        "${BLAS_LIBRARIES}"
626      )
627    endif()
628  endif()
629
630  # Elbrus Math Library?
631  if(NOT LAPACK_LIBRARIES
632      AND (BLA_VENDOR MATCHES "EML" OR BLA_VENDOR STREQUAL "All"))
633    if(BLAS_LIBRARIES MATCHES "eml.+")
634      set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
635    endif()
636  endif()
637
638  # Fujitsu SSL2 Library?
639  if(NOT LAPACK_LIBRARIES
640      AND (BLA_VENDOR MATCHES "Fujitsu_SSL2" OR BLA_VENDOR STREQUAL "All"))
641    if(BLAS_LIBRARIES MATCHES "fjlapack.+")
642      set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
643      set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
644    endif()
645  endif()
646
647  # LAPACK in IBM ESSL library?
648  if(NOT LAPACK_LIBRARIES
649      AND (BLA_VENDOR MATCHES "IBMESSL" OR BLA_VENDOR STREQUAL "All"))
650    if(BLAS_LIBRARIES MATCHES "essl.+")
651      set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
652    endif()
653  endif()
654
655  # NVHPC Library?
656
657  if(NOT LAPACK_LIBRARIES
658      AND (BLA_VENDOR MATCHES "NVHPC" OR BLA_VENDOR STREQUAL "All"))
659    set(_lapack_nvhpc_lib "lapack")
660
661    if(_lapack_sizeof_integer EQUAL 8)
662      string(APPEND _lapack_nvhpc_lib "_ilp64")
663    elseif(_lapack_sizeof_integer EQUAL 4)
664      string(APPEND _lapack_nvhpc_lib "_lp64")
665    endif()
666
667    check_lapack_libraries(
668      LAPACK_LIBRARIES
669      LAPACK
670      cheev
671      ""
672      "${_lapack_nvhpc_lib}"
673      "-fortranlibs"
674      ""
675      ""
676      "${BLAS_LIBRARIES}"
677    )
678
679    # an additional check for NVHPC 2020
680    # which does not have differentiation
681    # between lp64 and ilp64 modes
682    if(NOT LAPACK_LIBRARIES AND NOT _lapack_sizeof_integer EQUAL 8)
683      set(_lapack_nvhpc_lib "lapack")
684
685      check_lapack_libraries(
686        LAPACK_LIBRARIES
687        LAPACK
688        cheev
689        ""
690        "${_lapack_nvhpc_lib}"
691        "-fortranlibs"
692        ""
693        ""
694        "${BLAS_LIBRARIES}"
695      )
696    endif()
697
698    unset(_lapack_nvhpc_lib)
699  endif()
700
701  # Generic LAPACK library?
702  if(NOT LAPACK_LIBRARIES
703      AND (BLA_VENDOR STREQUAL "Generic"
704           OR BLA_VENDOR STREQUAL "ATLAS"
705           OR BLA_VENDOR STREQUAL "All"))
706    set(_lapack_generic_lib "lapack")
707    if(BLA_STATIC)
708      # We do not know for sure how the LAPACK reference implementation
709      # is built on this host.  Guess typical dependencies.
710      set(_lapack_generic_deps "-lgfortran;-lm")
711    else()
712      set(_lapack_generic_deps "")
713    endif()
714
715    if(_lapack_sizeof_integer EQUAL 8)
716      string(APPEND _lapack_generic_lib "64")
717    endif()
718
719    check_lapack_libraries(
720      LAPACK_LIBRARIES
721      LAPACK
722      cheev
723      ""
724      "${_lapack_generic_lib}"
725      "${_lapack_generic_deps}"
726      ""
727      ""
728      "${BLAS_LIBRARIES}"
729    )
730
731    unset(_lapack_generic_deps)
732    unset(_lapack_generic_lib)
733  endif()
734endif()
735
736if(BLA_F95)
737  set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}")
738endif()
739
740if(LAPACK_NOT_FOUND_MESSAGE)
741  set(LAPACK_NOT_FOUND_MESSAGE
742    REASON_FAILURE_MESSAGE ${LAPACK_NOT_FOUND_MESSAGE})
743endif()
744find_package_handle_standard_args(LAPACK REQUIRED_VARS ${_lapack_fphsa_req_var}
745  ${LAPACK_NOT_FOUND_MESSAGE})
746unset(LAPACK_NOT_FOUND_MESSAGE)
747
748if(BLA_F95)
749  set(LAPACK95_FOUND ${LAPACK_FOUND})
750endif()
751
752# On compilers that implicitly link LAPACK (such as ftn, cc, and CC on Cray HPC machines)
753# we used a placeholder for empty LAPACK_LIBRARIES to get through our logic above.
754if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
755  set(LAPACK_LIBRARIES "")
756endif()
757
758_add_lapack_target()
759unset(_lapack_fphsa_req_var)
760unset(_lapack_sizeof_integer)
761unset(_LAPACK_LIBRARIES)
762