Files
SpectraREML/CMakeLists.txt

121 lines
4.3 KiB
CMake

cmake_minimum_required(VERSION 3.20)
project(
SpectraREML
VERSION 0.1.0
DESCRIPTION "Reusable batched spectral AI-REML engine"
LANGUAGES CXX
)
include(GNUInstallDirs)
include(CTest)
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(REML_BLAS "MKL" CACHE STRING "BLAS/LAPACKE backend: MKL or OPENBLAS")
set_property(CACHE REML_BLAS PROPERTY STRINGS MKL OPENBLAS)
string(TOUPPER "${REML_BLAS}" REML_BLAS)
option(REML_ENABLE_OPENMP "Parallelize independent REML tasks with OpenMP" ON)
option(REML_ENABLE_NATIVE_ARCH "Enable compiler tuning for the build host" OFF)
add_library(reml_blas_lapacke INTERFACE)
add_library(REML::BLAS_LAPACKE ALIAS reml_blas_lapacke)
if(REML_BLAS STREQUAL "MKL")
# These variables are consumed by Intel's MKLConfig.cmake. Sequential is
# deliberately the portable default because tasks are parallelized with
# OpenMP; a threaded BLAS can otherwise create nested thread pools.
set(MKL_INTERFACE "lp64" CACHE STRING "oneMKL integer interface")
set(MKL_LINK "dynamic" CACHE STRING "oneMKL link type")
set(MKL_THREADING "sequential" CACHE STRING "oneMKL threading layer")
set_property(CACHE MKL_INTERFACE PROPERTY STRINGS lp64 ilp64)
set_property(CACHE MKL_LINK PROPERTY STRINGS dynamic static)
set_property(CACHE MKL_THREADING PROPERTY STRINGS sequential intel_thread gnu_thread tbb_thread)
find_package(MKL CONFIG REQUIRED)
if(NOT TARGET MKL::MKL)
message(FATAL_ERROR "MKL was found, but its MKL::MKL CMake target is missing")
endif()
target_link_libraries(reml_blas_lapacke INTERFACE MKL::MKL)
target_compile_definitions(reml_blas_lapacke INTERFACE REML_BLAS_MKL=1)
elseif(REML_BLAS STREQUAL "OPENBLAS")
find_package(REML_OpenBLAS REQUIRED)
target_link_libraries(reml_blas_lapacke INTERFACE REML::OpenBLASLAPACKE)
target_compile_definitions(reml_blas_lapacke INTERFACE REML_BLAS_OPENBLAS=1)
else()
message(FATAL_ERROR "Unsupported REML_BLAS='${REML_BLAS}'. Choose MKL or OPENBLAS.")
endif()
if(REML_ENABLE_OPENMP)
find_package(OpenMP REQUIRED COMPONENTS CXX)
endif()
add_library(spectra_reml_core STATIC
src/linalg.cpp
src/grm.cpp
src/distributions.cpp
src/reml_core.cpp
src/fixed_effects.cpp
src/batch_io.cpp
)
add_library(SpectraREML::core ALIAS spectra_reml_core)
target_compile_features(spectra_reml_core PUBLIC cxx_std_17)
target_include_directories(spectra_reml_core
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_link_libraries(spectra_reml_core PUBLIC REML::BLAS_LAPACKE)
if(REML_ENABLE_OPENMP)
target_link_libraries(spectra_reml_core PUBLIC OpenMP::OpenMP_CXX)
target_compile_definitions(spectra_reml_core PUBLIC REML_USE_OPENMP=1)
endif()
if(MSVC)
target_compile_options(spectra_reml_core PRIVATE /W4 /permissive- /EHsc)
else()
target_compile_options(spectra_reml_core PRIVATE -Wall -Wextra -Wpedantic)
target_compile_definitions(spectra_reml_core PUBLIC _FILE_OFFSET_BITS=64)
if(REML_ENABLE_NATIVE_ARCH)
target_compile_options(spectra_reml_core PRIVATE -march=native)
endif()
endif()
add_executable(spectra_reml src/main.cpp)
target_link_libraries(spectra_reml PRIVATE SpectraREML::core)
target_compile_features(spectra_reml PRIVATE cxx_std_17)
if(MSVC)
target_compile_options(spectra_reml PRIVATE /W4 /permissive- /EHsc)
else()
target_compile_options(spectra_reml PRIVATE -Wall -Wextra -Wpedantic)
if(REML_ENABLE_NATIVE_ARCH)
target_compile_options(spectra_reml PRIVATE -march=native)
endif()
endif()
if(BUILD_TESTING)
add_executable(test_reml_synthetic tests/cpp/test_reml_synthetic.cpp)
target_link_libraries(test_reml_synthetic PRIVATE SpectraREML::core)
add_test(NAME reml_synthetic COMMAND test_reml_synthetic)
add_executable(test_grm_io tests/cpp/test_grm_io.cpp)
target_link_libraries(test_grm_io PRIVATE SpectraREML::core)
add_test(NAME grm_io COMMAND test_grm_io)
endif()
install(TARGETS spectra_reml_core spectra_reml
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
message(STATUS "SpectraREML ${PROJECT_VERSION}")
message(STATUS " BLAS/LAPACKE backend : ${REML_BLAS}")
message(STATUS " OpenMP : ${REML_ENABLE_OPENMP}")
message(STATUS " Native architecture : ${REML_ENABLE_NATIVE_ARCH}")