Add reusable SpectraREML batch AI-REML engine
This commit is contained in:
135
cmake/FindREML_OpenBLAS.cmake
Normal file
135
cmake/FindREML_OpenBLAS.cmake
Normal file
@@ -0,0 +1,135 @@
|
||||
# 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
|
||||
)
|
||||
Reference in New Issue
Block a user