Skip to content

Commit

Permalink
CMake: Fix/cleanup BLAS linking (#2357)
Browse files Browse the repository at this point in the history
No matter how we found the BLAS, make sure there is always BLAS::BLAS.

Closes #2354
  • Loading branch information
dweindl authored Mar 6, 2024
1 parent b8be5a0 commit 46d9d88
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 102 deletions.
97 changes: 10 additions & 87 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ endif()
# find dependencies
include(GNUInstallDirs)

include(AmiciFindBLAS)
find_package(OpenMP)
find_package(Boost COMPONENTS chrono)

Expand All @@ -142,75 +143,6 @@ message(STATUS "Found SUNDIALS: ${SUNDIALS_DIR}")

set(GSL_LITE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/gsl")

# AMICI requires BLAS, currently Intel MKL, CBLAS or MATLAB BLAS can be used.
# The latter is not supported via CMake yet.
set(BLAS
"CBLAS"
CACHE STRING "BLAS library to use")
set_property(CACHE BLAS PROPERTY STRINGS "CBLAS" "MKL" "ACCELERATE")
if(${BLAS} STREQUAL "MKL" OR DEFINED ENV{MKLROOT})
if(DEFINED ENV{MKLROOT})
# This is set by Environment Modules
message(STATUS "Using MKL_INCDIR and MKL_LIB from environment module")
set(BLAS
"MKL"
CACHE STRING "BLAS library to use" FORCE)
set(BLAS_INCLUDE_DIRS
"$ENV{MKL_INCDIR}"
CACHE STRING "" FORCE)
set(BLAS_LIBRARIES
"$ENV{MKL_LIB}"
CACHE STRING "" FORCE)
else()
set(BLAS_INCLUDE_DIRS
""
CACHE STRING "")
set(BLAS_LIBRARIES
-lmkl
CACHE STRING "")
endif()
elseif(
NOT DEFINED ENV{BLAS_LIBS}
AND NOT DEFINED ENV{BLAS_CFLAGS}
AND NOT BLAS_FOUND)
# if nothing is specified via environment variables, let's try FindBLAS
if($(CMAKE_VERSION) VERSION_GREATER_EQUAL 3.22)
set(BLA_SIZEOF_INTEGER 8)
endif()

if(APPLE AND (NOT DEFINED BLA_VENDOR OR BLA_VENDOR STREQUAL "All"))
set(BLA_VENDOR Apple)
find_package(BLAS)
if(BLAS_FOUND)
set_property(
TARGET BLAS::BLAS
APPEND
PROPERTY INTERFACE_COMPILE_DEFINITIONS ACCELERATE_NEW_LAPACK)
set_property(
TARGET BLAS::BLAS
APPEND
PROPERTY INTERFACE_COMPILE_DEFINITIONS ACCELERATE_LAPACK_ILP64)
else()
set(BLA_VENDOR "All")
endif()

endif()
if(NOT BLAS_FOUND)
find_package(BLAS)
endif()
if(NOT BLAS_FOUND)
# Nothing specified by the user and FindBLAS didn't find anything; let's try
# if cblas is available on the system paths.
set(BLAS_INCLUDE_DIRS
""
CACHE STRING "")
set(BLAS_LIBRARIES
-lcblas
CACHE STRING "")
endif()
endif()
add_compile_definitions(AMICI_BLAS_${BLAS})

# Add target to create version file
add_custom_target(
version
Expand Down Expand Up @@ -285,16 +217,6 @@ set(AMICI_SRC_LIST

add_library(${PROJECT_NAME} ${AMICI_SRC_LIST})

# legacy python package environment variables:
if(DEFINED ENV{BLAS_CFLAGS})
target_compile_options(${PROJECT_NAME} PRIVATE "$ENV{BLAS_CFLAGS}")
endif()
if(DEFINED ENV{BLAS_LIBS})
# Note that, on Windows, at least for ninja, this will only work with dashes
# instead of slashes in any linker options
target_link_libraries(${PROJECT_NAME} PUBLIC "$ENV{BLAS_LIBS}")
endif()

set(AMICI_CXX_OPTIONS
""
CACHE STRING "C++ options for libamici (semicolon-separated)")
Expand All @@ -315,10 +237,6 @@ target_include_directories(
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/swig>
PRIVATE ${SUNDIALS_PRIVATE_INCLUDE_DIRS})

if(NOT "${BLAS_INCLUDE_DIRS}" STREQUAL "")
target_include_directories(${PROJECT_NAME} PUBLIC ${BLAS_INCLUDE_DIRS})
endif()

if("$ENV{ENABLE_AMICI_DEBUGGING}"
OR "$ENV{ENABLE_GCOV_COVERAGE}"
OR CMAKE_BUILD_TYPE MATCHES "Debug")
Expand Down Expand Up @@ -354,11 +272,11 @@ target_link_libraries(
SUNDIALS::sunnonlinsolfixedpoint_static
SUNDIALS::cvodes_static
SUNDIALS::idas_static
${BLAS_LIBRARIES}
$<$<BOOL:${Boost_CHRONO_FOUND}>:Boost::chrono>
$<$<BOOL:${OpenMP_FOUND}>:OpenMP::OpenMP_CXX>
${CMAKE_DL_LIBS}
PRIVATE
BLAS::BLAS
$<$<BOOL:${SUNDIALS_SUPERLUMT_ENABLE}>:SUNDIALS::sundials_sunlinsolsuperlumt>
)

Expand Down Expand Up @@ -457,16 +375,21 @@ install(
EXPORT AmiciTargets
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Amici"
NAMESPACE Upstream::)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/AmiciConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/AmiciConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Amici)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/AmiciConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/AmiciConfigVersion.cmake
${CMAKE_CURRENT_LIST_DIR}/cmake/AmiciFindBLAS.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Amici)

install(DIRECTORY ThirdParty/gsl/gsl TYPE INCLUDE)
# When running from setup.py, this is a symlink we need to dereference
get_filename_component(_swig_realpath "swig" REALPATH)
install(DIRECTORY "${_swig_realpath}"
DESTINATION ${CMAKE_INSTALL_DATADIR}/amici)

configure_file(cmake/AmiciFindBLAS.cmake
${CMAKE_CURRENT_BINARY_DIR}/AmiciFindBLAS.cmake COPYONLY)

# Register package?
if(EXPORT_PACKAGE)
export(PACKAGE Amici)
Expand Down
25 changes: 10 additions & 15 deletions cmake/AmiciConfig.cmake
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
@PACKAGE_INIT@

# TODO remove after cmake files for test models have been regenerated
# cmake >=3.27
if(POLICY CMP0144)
cmake_policy(SET CMP0144 NEW)
endif(POLICY CMP0144)


include(CMakeFindDependencyMacro)

find_package(OpenMP)
Expand All @@ -31,11 +24,13 @@ endif()
if(NOT DEFINED KLU_ROOT)
set(KLU_ROOT @CMAKE_SOURCE_DIR@/ThirdParty/SuiteSparse/)
endif()
find_package(SuiteSparse_config REQUIRED)
find_package(AMD REQUIRED)
find_package(BTF REQUIRED)
find_package(COLAMD REQUIRED)
find_package(KLU REQUIRED)
find_dependency(SuiteSparse_config REQUIRED)
find_dependency(AMD REQUIRED)
find_dependency(BTF REQUIRED)
find_dependency(COLAMD REQUIRED)
find_dependency(KLU REQUIRED)

include("${CMAKE_CURRENT_LIST_DIR}/AmiciFindBLAS.cmake")

add_library(SUNDIALS::KLU INTERFACE IMPORTED)
target_link_libraries(
Expand All @@ -48,15 +43,15 @@ target_link_libraries(
set_target_properties(SUNDIALS::KLU PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
"${KLU_INCLUDE_DIR}")

find_package(SUNDIALS REQUIRED PATHS
find_dependency(SUNDIALS REQUIRED PATHS
"@CMAKE_SOURCE_DIR@/ThirdParty/sundials/build/@CMAKE_INSTALL_LIBDIR@/cmake/sundials/")

if(@Boost_CHRONO_FOUND@)
find_package(Boost COMPONENTS chrono REQUIRED)
find_dependency(Boost COMPONENTS chrono REQUIRED)
endif()

if(@HDF5_FOUND@)
find_package(
find_dependency(
HDF5
COMPONENTS C HL CXX
REQUIRED)
Expand Down
110 changes: 110 additions & 0 deletions cmake/AmiciFindBLAS.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Find a BLAS
#
# AMICI requires BLAS, currently Intel MKL, CBLAS or MATLAB BLAS can be used.
# The latter is not supported via CMake yet.
#
# This module defines the BLAS::BLAS IMPORTED target.

set(BLAS
"CBLAS"
CACHE STRING "BLAS library to use")
set_property(CACHE BLAS PROPERTY STRINGS "CBLAS" "MKL" "ACCELERATE")

if(${BLAS} STREQUAL "MKL" OR DEFINED ENV{MKLROOT})
if(DEFINED ENV{MKLROOT})
# This is set by Environment Modules
message(STATUS "Using MKL_INCDIR and MKL_LIB from environment module")
set(BLAS
"MKL"
CACHE STRING "BLAS library to use" FORCE)
set(BLAS_INCLUDE_DIRS
"$ENV{MKL_INCDIR}"
CACHE STRING "" FORCE)
set(BLAS_LIBRARIES
"$ENV{MKL_LIB}"
CACHE STRING "" FORCE)
else()
set(BLAS_INCLUDE_DIRS
""
CACHE STRING "")
set(BLAS_LIBRARIES
-lmkl
CACHE STRING "")
endif()
elseif(
NOT DEFINED ENV{BLAS_LIBS}
AND NOT DEFINED ENV{BLAS_CFLAGS}
AND NOT BLAS_FOUND)
# if nothing is specified via environment variables, let's try FindBLAS
if($(CMAKE_VERSION) VERSION_GREATER_EQUAL 3.22)
set(BLA_SIZEOF_INTEGER 8)
endif()

if(APPLE AND (NOT DEFINED BLA_VENDOR OR BLA_VENDOR STREQUAL "All"))
set(BLA_VENDOR Apple)
find_package(BLAS)
if(BLAS_FOUND)
message(STATUS "Found Apple Accelerate BLAS")
set_property(
TARGET BLAS::BLAS
APPEND
PROPERTY INTERFACE_COMPILE_DEFINITIONS ACCELERATE_NEW_LAPACK)
set_property(
TARGET BLAS::BLAS
APPEND
PROPERTY INTERFACE_COMPILE_DEFINITIONS ACCELERATE_LAPACK_ILP64)
else()
set(BLA_VENDOR "All")
endif()

endif()
if(NOT BLAS_FOUND)
find_package(BLAS)
if(BLAS_FOUND)
message(STATUS "Found BLAS via FindBLAS")
endif()
endif()
if(NOT BLAS_FOUND)
# Nothing specified by the user and FindBLAS didn't find anything; let's try
# if cblas is available on the system paths.
set(BLAS_INCLUDE_DIRS
""
CACHE STRING "")
set(BLAS_LIBRARIES
-lcblas
CACHE STRING "")
endif()
endif()

# Create an imported target
if(NOT TARGET BLAS::BLAS)
add_library(BLAS INTERFACE)
set_target_properties(BLAS PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${BLAS_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}")
add_library(BLAS::BLAS ALIAS BLAS)
install(TARGETS BLAS EXPORT BLAS)
export(EXPORT BLAS NAMESPACE BLAS::)
install(
EXPORT BLAS
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Amici"
NAMESPACE BLAS::)


# legacy python package environment variables:
if(DEFINED ENV{BLAS_CFLAGS})
target_compile_options(BLAS INTERFACE "$ENV{BLAS_CFLAGS}")
endif()
if(DEFINED ENV{BLAS_LIBS})
# Note that, on Windows, at least for ninja, this will only work with dashes
# instead of slashes in any linker options
target_link_libraries(BLAS INTERFACE "$ENV{BLAS_LIBS}")
endif()

if(NOT "${BLAS_INCLUDE_DIRS}" STREQUAL "")
target_include_directories(BLAS INTERFACE ${BLAS_INCLUDE_DIRS})
endif()
target_compile_definitions(BLAS INTERFACE "AMICI_BLAS_${BLAS}")
else()
target_compile_definitions(BLAS::BLAS INTERFACE "AMICI_BLAS_${BLAS}")
endif()

0 comments on commit 46d9d88

Please sign in to comment.