136 lines
4.1 KiB
CMake
136 lines
4.1 KiB
CMake
|
|
# Locate an LP64 OpenBLAS implementation together with the CBLAS and LAPACKE
|
||
|
|
# C interfaces. LAPACKE may be provided by libopenblas itself or by a separate
|
||
|
|
# liblapacke library.
|
||
|
|
#
|
||
|
|
# Result:
|
||
|
|
# REML_OpenBLAS_FOUND
|
||
|
|
# REML::OpenBLASLAPACKE
|
||
|
|
#
|
||
|
|
# Optional hints/overrides:
|
||
|
|
# OpenBLAS_ROOT
|
||
|
|
# LAPACKE_ROOT
|
||
|
|
# REML_OPENBLAS_LIBRARY
|
||
|
|
# REML_LAPACKE_LIBRARY
|
||
|
|
# REML_CBLAS_INCLUDE_DIR
|
||
|
|
# REML_LAPACKE_INCLUDE_DIR
|
||
|
|
|
||
|
|
include(CheckCXXSourceCompiles)
|
||
|
|
include(CMakePushCheckState)
|
||
|
|
include(FindPackageHandleStandardArgs)
|
||
|
|
|
||
|
|
set(_reml_openblas_hints)
|
||
|
|
foreach(_root IN ITEMS "${OpenBLAS_ROOT}" "$ENV{OpenBLAS_ROOT}" "$ENV{OPENBLAS_ROOT}" "$ENV{CONDA_PREFIX}")
|
||
|
|
if(_root)
|
||
|
|
list(APPEND _reml_openblas_hints "${_root}")
|
||
|
|
endif()
|
||
|
|
endforeach()
|
||
|
|
|
||
|
|
set(_reml_lapacke_hints ${_reml_openblas_hints})
|
||
|
|
foreach(_root IN ITEMS "${LAPACKE_ROOT}" "$ENV{LAPACKE_ROOT}")
|
||
|
|
if(_root)
|
||
|
|
list(PREPEND _reml_lapacke_hints "${_root}")
|
||
|
|
endif()
|
||
|
|
endforeach()
|
||
|
|
|
||
|
|
# Prefer package-provided imported targets because they carry static-library
|
||
|
|
# dependencies (Fortran runtime, pthreads, and libm) correctly.
|
||
|
|
find_package(OpenBLAS CONFIG QUIET)
|
||
|
|
if(TARGET OpenBLAS::OpenBLAS)
|
||
|
|
set(_reml_openblas_link OpenBLAS::OpenBLAS)
|
||
|
|
elseif(TARGET OpenBLAS)
|
||
|
|
set(_reml_openblas_link OpenBLAS)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
if(NOT _reml_openblas_link)
|
||
|
|
find_library(REML_OPENBLAS_LIBRARY
|
||
|
|
NAMES openblas libopenblas
|
||
|
|
HINTS ${_reml_openblas_hints}
|
||
|
|
PATH_SUFFIXES lib lib64 Library/lib
|
||
|
|
)
|
||
|
|
if(REML_OPENBLAS_LIBRARY)
|
||
|
|
set(_reml_openblas_link "${REML_OPENBLAS_LIBRARY}")
|
||
|
|
endif()
|
||
|
|
endif()
|
||
|
|
|
||
|
|
find_path(REML_CBLAS_INCLUDE_DIR
|
||
|
|
NAMES cblas.h
|
||
|
|
HINTS ${_reml_openblas_hints}
|
||
|
|
PATH_SUFFIXES include include/openblas Library/include Library/include/openblas
|
||
|
|
)
|
||
|
|
find_path(REML_LAPACKE_INCLUDE_DIR
|
||
|
|
NAMES lapacke.h
|
||
|
|
HINTS ${_reml_lapacke_hints}
|
||
|
|
PATH_SUFFIXES include include/openblas include/lapacke Library/include Library/include/openblas
|
||
|
|
)
|
||
|
|
|
||
|
|
find_package(LAPACKE CONFIG QUIET)
|
||
|
|
if(TARGET LAPACKE::LAPACKE)
|
||
|
|
set(_reml_lapacke_link LAPACKE::LAPACKE)
|
||
|
|
elseif(TARGET LAPACKE)
|
||
|
|
set(_reml_lapacke_link LAPACKE)
|
||
|
|
else()
|
||
|
|
find_library(REML_LAPACKE_LIBRARY
|
||
|
|
NAMES lapacke liblapacke
|
||
|
|
HINTS ${_reml_lapacke_hints}
|
||
|
|
PATH_SUFFIXES lib lib64 Library/lib
|
||
|
|
)
|
||
|
|
if(REML_LAPACKE_LIBRARY)
|
||
|
|
set(_reml_lapacke_link "${REML_LAPACKE_LIBRARY}")
|
||
|
|
endif()
|
||
|
|
endif()
|
||
|
|
|
||
|
|
if(_reml_lapacke_link)
|
||
|
|
# Keep the static-link order dependency first, provider second:
|
||
|
|
# liblapacke calls LAPACK symbols supplied by libopenblas.
|
||
|
|
set(_reml_link_items ${_reml_lapacke_link} ${_reml_openblas_link})
|
||
|
|
else()
|
||
|
|
set(_reml_link_items ${_reml_openblas_link})
|
||
|
|
endif()
|
||
|
|
|
||
|
|
unset(REML_OPENBLAS_LINK_OK CACHE)
|
||
|
|
if(REML_CBLAS_INCLUDE_DIR AND REML_LAPACKE_INCLUDE_DIR AND _reml_openblas_link)
|
||
|
|
cmake_push_check_state(RESET)
|
||
|
|
set(CMAKE_REQUIRED_INCLUDES "${REML_CBLAS_INCLUDE_DIR};${REML_LAPACKE_INCLUDE_DIR}")
|
||
|
|
set(CMAKE_REQUIRED_LIBRARIES ${_reml_link_items})
|
||
|
|
check_cxx_source_compiles([[
|
||
|
|
#include <cblas.h>
|
||
|
|
#include <lapacke.h>
|
||
|
|
int main() {
|
||
|
|
double a[1] = {1.0};
|
||
|
|
double b[1] = {1.0};
|
||
|
|
double c[1] = {0.0};
|
||
|
|
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
|
||
|
|
1, 1, 1, 1.0, a, 1, b, 1, 0.0, c, 1);
|
||
|
|
return LAPACKE_dpotrf(LAPACK_ROW_MAJOR, 'L', 1, a, 1);
|
||
|
|
}
|
||
|
|
]] REML_OPENBLAS_LINK_OK)
|
||
|
|
cmake_pop_check_state()
|
||
|
|
else()
|
||
|
|
set(REML_OPENBLAS_LINK_OK FALSE)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
find_package_handle_standard_args(REML_OpenBLAS
|
||
|
|
REQUIRED_VARS
|
||
|
|
REML_CBLAS_INCLUDE_DIR
|
||
|
|
REML_LAPACKE_INCLUDE_DIR
|
||
|
|
_reml_openblas_link
|
||
|
|
REML_OPENBLAS_LINK_OK
|
||
|
|
FAIL_MESSAGE
|
||
|
|
"OpenBLAS with LP64 CBLAS and LAPACKE is required. Set OpenBLAS_ROOT/LAPACKE_ROOT, or the REML_* cache variables listed in cmake/FindREML_OpenBLAS.cmake."
|
||
|
|
)
|
||
|
|
|
||
|
|
if(REML_OpenBLAS_FOUND AND NOT TARGET REML::OpenBLASLAPACKE)
|
||
|
|
add_library(REML::OpenBLASLAPACKE INTERFACE IMPORTED)
|
||
|
|
set_property(TARGET REML::OpenBLASLAPACKE PROPERTY
|
||
|
|
INTERFACE_INCLUDE_DIRECTORIES "${REML_CBLAS_INCLUDE_DIR};${REML_LAPACKE_INCLUDE_DIR}")
|
||
|
|
set_property(TARGET REML::OpenBLASLAPACKE PROPERTY
|
||
|
|
INTERFACE_LINK_LIBRARIES "${_reml_link_items}")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
mark_as_advanced(
|
||
|
|
REML_CBLAS_INCLUDE_DIR
|
||
|
|
REML_LAPACKE_INCLUDE_DIR
|
||
|
|
REML_OPENBLAS_LIBRARY
|
||
|
|
REML_LAPACKE_LIBRARY
|
||
|
|
)
|