forked from wavefunction91/linalg-cmake-modules
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FindLAPACK.cmake
200 lines (156 loc) · 6.88 KB
/
FindLAPACK.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
cmake_minimum_required( VERSION 3.17 ) # Require CMake 3.17+
include( CMakePushCheckState )
include( CheckLibraryExists )
include( CheckSymbolExists )
include( CMakeFindDependencyMacro )
include( FindPackageHandleStandardArgs )
include( ${CMAKE_CURRENT_LIST_DIR}/util/CommonFunctions.cmake )
include( ${CMAKE_CURRENT_LIST_DIR}/util/LAPACKUtilities.cmake )
include( ${CMAKE_CURRENT_LIST_DIR}/LinAlgModulesMacros.cmake )
# SANITY CHECK
if( "ilp64" IN_LIST LAPACK_FIND_COMPONENTS AND "lp64" IN_LIST LAPACK_FIND_COMPONENTS )
message( FATAL_ERROR "LAPACK cannot link to both ILP64 and LP64 interfaces" )
endif()
# Get list of required / optional components
foreach( _comp ${LAPACK_FIND_COMPONENTS} )
if( LAPACK_FIND_REQUIRED_${_comp} )
list( APPEND LAPACK_REQUIRED_COMPONENTS ${_comp} )
else()
list( APPEND LAPACK_OPTIONAL_COMPONENTS ${_comp} )
endif()
endforeach()
emulate_kitware_linalg_modules( LAPACK )
fill_out_prefix( LAPACK )
if( NOT LAPACK_PREFERENCE_LIST )
set( LAPACK_PREFERENCE_LIST "ReferenceLAPACK" "FLAME" )
endif()
if( NOT LAPACK_LIBRARIES )
# Find BLAS
if( NOT TARGET BLAS::BLAS )
copy_meta_data( LAPACK BLAS )
find_dependency( BLAS
COMPONENTS ${LAPACK_REQUIRED_COMPONENTS}
OPTIONAL_COMPONENTS ${LAPACK_OPTIONAL_COMPONENTS}
)
endif()
# Check if BLAS contains a LAPACK linker
message( STATUS "LAPACK_LIBRARIES Not Given: Checking for LAPACK in BLAS" )
set( LAPACK_LIBRARIES ${BLAS_LIBRARIES} )
set( LAPACK_INCLUDE_DIRS ${BLAS_INCLUDE_DIRS} )
set( LAPACK_COMPILE_DEFINITIONS ${BLAS_COMPILE_DEFINITIONS} )
# use dpstrf to check for full LAPACK API ... some implementations are incomplete (e.g. older OpenBLAS)
# also need to handle several corner cases:
# - OpenBLAS needs libgfortran only for some functions, dpstrf is not one of them, so check for dgesvd
check_fortran_functions_exist( "dpstrf;dgesvd" LAPACK LAPACK_LIBRARIES
BLAS_HAS_LAPACK LAPACK_Fortran_LOWER LAPACK_Fortran_UNDERSCORE
)
# If BLAS has a full LAPACK Linker, propagate vars
if( BLAS_HAS_LAPACK )
message( STATUS "BLAS Has A Full LAPACK Linker" )
set( LAPACK_VENDOR ${BLAS_VENDOR} )
set( LAPACK_IS_LP64 ${BLAS_IS_LP64} )
set( LAPACK_blacs_FOUND ${BLAS_blacs_FOUND} )
set( LAPACK_scalapack_FOUND ${BLAS_scalapack_FOUND} )
set( LAPACK_sycl_FOUND ${BLAS_sycl_FOUND} )
# Else find LAPACK installation consistent with BLAS
else( BLAS_HAS_LAPACK )
# Ensure proper integer size
if( BLAS_IS_LP64 AND (NOT "lp64" IN_LIST LAPACK_REQUIRED_COMPONENTS) )
list( APPEND LAPACK_REQUIRED_COMPONENTS "lp64" )
elseif( (NOT BLAS_IS_LP64) AND (NOT "ilp64" IN_LIST LAPACK_REQUIRED_COMPONENTS ) )
list( APPEND LAPACK_REQUIRED_COMPONENTS "ilp64" )
endif()
message( STATUS "BLAS Does Not Have A Full LAPACK Linker -- Performing Search" )
foreach( lapack_type ${LAPACK_PREFERENCE_LIST} )
copy_meta_data( LAPACK ${lapack_type} )
find_package( ${lapack_type}
COMPONENTS ${LAPACK_REQUIRED_COMPONENTS}
OPTIONAL_COMPONENTS ${LAPACK_OPTIONAL_COMPONENTS}
)
if( ${lapack_type}_FOUND )
# Propagate Linker / Includes
set( LAPACK_VENDOR "${lapack_type}" )
list( PREPEND LAPACK_LIBRARIES ${${lapack_type}_LIBRARIES} )
list( PREPEND LAPACK_COMPILE_DEFINITIONS ${${lapack_type}_COMPILE_DEFINITIONS} )
list( PREPEND LAPACK_INCLUDE_DIR ${${lapack_type}_INCLUDE_DIR} )
# Generic Components
#set( LAPACK_headers_FOUND ${${lapack_type}_headers_FOUND} )
set( LAPACK_blacs_FOUND ${${lapack_type}_blacs_FOUND} )
set( LAPACK_scalapack_FOUND ${${lapack_type}_scalapack_FOUND} )
set( LAPACK_sycl_FOUND ${${lapack_type}_sycl_FOUND} )
break() # Break from search loop
endif()
endforeach()
endif( BLAS_HAS_LAPACK )
else()
find_linalg_dependencies( LAPACK_LIBRARIES )
endif()
# Handle implicit LAPACK linkage
if( LAPACK_LIBRARIES MATCHES "[Ii][Mm][Pp][Ll][Ii][Cc][Ii][Tt]" )
unset( LAPACK_LIBRARIES )
endif()
# Check for LAPACK Linker
if( BLAS_HAS_LAPACK )
set( LAPACK_LINK_OK TRUE )
else()
# see notes above the first invocation of check_fortran_functions_exist
check_fortran_functions_exist( "dpstrf;dgesvd" LAPACK LAPACK_LIBRARIES
LAPACK_LINK_OK LAPACK_Fortran_LOWER LAPACK_Fortran_UNDERSCORE
)
endif()
# If LAPACK linkage successful, check if it is ILP64/LP64
if( LAPACK_LINK_OK )
set( _dsyev_name "dsyev" )
if( NOT LAPACK_Fortran_LOWER )
string( TOUPPER "${_dsyev_name}" _dsyev_name )
endif()
if( LAPACK_Fortran_UNDERSCORE )
set( _dsyev_name "${_dsyev_name}_" )
endif()
check_lapack_int( LAPACK_LIBRARIES ${_dsyev_name} LAPACK_IS_LP64 )
if( LAPACK_IS_LP64 )
set( LAPACK_lp64_FOUND TRUE )
set( LAPACK_ilp64_FOUND FALSE )
else()
set( LAPACK_lp64_FOUND FALSE )
set( LAPACK_ilp64_FOUND TRUE )
find_dependency( ILP64 )
list( APPEND LAPACK_COMPILE_OPTIONS "${ILP64_COMPILE_OPTIONS}" )
foreach ( lang C CXX Fortran )
if ( DEFINED ILP64_${lang}_COMPILE_OPTIONS )
list( APPEND LAPACK_${lang}_COMPILE_OPTIONS "${ILP64_${lang}_COMPILE_OPTIONS}" )
endif()
endforeach()
endif()
else()
# Unset everything for safety
unset( LAPACK_LIBRARIES )
unset( LAPACK_COMPILE_DEFINITIONS )
endif()
find_package_handle_standard_args( LAPACK
REQUIRED_VARS LAPACK_LINK_OK
HANDLE_COMPONENTS
)
# Cache variables
if( LAPACK_FOUND )
set( LAPACK_VENDOR "${LAPACK_VENDOR}" CACHE STRING "LAPACK Vendor" FORCE )
set( LAPACK_IS_LP64 "${LAPACK_IS_LP64}" CACHE STRING "LAPACK LP64 Flag" FORCE )
set( LAPACK_LIBRARIES "${LAPACK_LIBRARIES}" CACHE STRING "LAPACK Libraries" FORCE )
set( LAPACK_COMPILE_DEFINITIONS "${LAPACK_COMPILE_DEFINITIONS}" CACHE STRING "LAPACK Compile Definitions" FORCE )
set( LAPACK_INCLUDE_DIRS "${LAPACK_INCLUDE_DIRS}" CACHE STRING "LAPACK Include Directories" FORCE )
set( LAPACK_COMPILE_OPTIONS "${LAPACK_COMPILE_OPTIONS}" CACHE STRING "LAPACK Compile Options" FORCE )
foreach ( lang C CXX Fortran )
if ( DEFINED LAPACK_${lang}_COMPILE_OPTIONS )
set( LAPACK_${lang}_COMPILE_OPTIONS "${LAPACK_${lang}_COMPILE_OPTIONS}" CACHE STRING "LAPACK Compile Options for Language ${lang}" FORCE )
endif()
endforeach()
endif()
if( LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK )
add_library( LAPACK::LAPACK INTERFACE IMPORTED )
set_target_properties( LAPACK::LAPACK PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${LAPACK_INCLUDE_DIRS}"
INTERFACE_COMPILE_OPTIONS "${LAPACK_COMPILE_OPTIONS}"
INTERFACE_COMPILE_DEFINITIONS "${LAPACK_COMPILE_DEFINITIONS}"
INTERFACE_LINK_LIBRARIES "${LAPACK_LIBRARIES}"
)
endif()