diff --git a/FindLAPACK.cmake b/FindLAPACK.cmake new file mode 100644 index 0000000..f8f1c15 --- /dev/null +++ b/FindLAPACK.cmake @@ -0,0 +1,88 @@ +# +# CMake recipes +# +# Copyright (c) 2018-2021, ETH Zurich +# BSD 3-Clause License. All rights reserved. +# +# author: Alberto Invernizzi (a.invernizzi@cscs.ch) +# + +# Find LAPACK library +# +# LAPACK depends on BLAS and it is up to the user to honor this dependency by specifying +# all the dependencies for the selected LAPACK implementation. +# +# Users can manually specify next variables (even by setting them empty to force use of +# the compiler implicit linking) to control which implementation they want to use: +# LAPACK_LIBRARY +# ;-list of {lib name, lib filepath, -Llibrary_folder} +# +# This module sets the following variables: +# LAPACK_FOUND - set to true if a library implementing the LAPACK interface is found +# +# If LAPACK symbols got found, it creates target LAPACK::LAPACK + +macro(_lapack_check_is_working) + include(CMakePushCheckState) + cmake_push_check_state(RESET) + + include(CheckFunctionExists) + + set(CMAKE_REQUIRED_QUIET TRUE) + + if (NOT LAPACK_LIBRARY STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + list(APPEND CMAKE_REQUIRED_LIBRARIES ${LAPACK_LIBRARY}) + endif() + + unset(_LAPACK_CHECK_BLAS CACHE) + check_function_exists(dgemm_ _LAPACK_CHECK_BLAS) + if (NOT _LAPACK_CHECK_BLAS) + message(FATAL_ERROR "BLAS symbol not found with this configuration") + endif() + + unset(_LAPACK_CHECK CACHE) + check_function_exists(dpotrf_ _LAPACK_CHECK) + if (NOT _LAPACK_CHECK) + message(FATAL_ERROR "LAPACK symbol not found with this configuration") + endif() + + cmake_pop_check_state() +endmacro() + + +# Dependencies +set(_DEPS "") + +if (LAPACK_LIBRARY STREQUAL "" OR NOT LAPACK_LIBRARY) + set(LAPACK_LIBRARY "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") +endif() + +mark_as_advanced( + LAPACK_LIBRARY +) + +_lapack_check_is_working() + +### Package +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LAPACK DEFAULT_MSG + LAPACK_LIBRARY + _LAPACK_CHECK + _LAPACK_CHECK_BLAS +) + +# Remove the placeholder +if (LAPACK_LIBRARY STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + set(LAPACK_LIBRARY "") +endif() + +if (LAPACK_FOUND) + if (NOT TARGET LAPACK::LAPACK) + add_library(LAPACK::LAPACK INTERFACE IMPORTED GLOBAL) + endif() + + target_link_libraries(LAPACK::LAPACK INTERFACE + "${LAPACK_LIBRARY}" + "${_DEPS}" + ) +endif() diff --git a/FindSCALAPACK.cmake b/FindSCALAPACK.cmake new file mode 100644 index 0000000..283ff15 --- /dev/null +++ b/FindSCALAPACK.cmake @@ -0,0 +1,98 @@ +# +# CMake recipes +# +# Copyright (c) 2018-2021, ETH Zurich +# BSD 3-Clause License. All rights reserved. +# +# author: Alberto Invernizzi (a.invernizzi@cscs.ch) +# + +# Find SCALAPACK library +# +# ScaLAPACK depends on MPI and LAPACK, so it depends on other modules for their respective +# targets LAPACK::LAPACK and MPI::MPI_. In particular, for the latter one, this module checks +# which language is enabled in the project and it adds all needed dependencies. +# +# Users can manually specify next variables (even by setting them empty to force use of +# the compiler implicit linking) to control which implementation they want to use: +# SCALAPACK_LIBRARY +# ;-list of {lib name, lib filepath, -Llibrary_folder} +# +# This module sets the following variables: +# SCALAPACK_FOUND - set to true if a library implementing the SCALAPACK interface is found +# +# If ScaLAPACK symbols got found, it creates target SCALAPACK::SCALAPACK + +cmake_minimum_required(VERSION 3.12) + +macro(_scalapack_check_is_working) + include(CMakePushCheckState) + cmake_push_check_state(RESET) + + set(CMAKE_REQUIRED_QUIET TRUE) + set(CMAKE_REQUIRED_LIBRARIES ${_DEPS}) + if (NOT SCALAPACK_LIBRARY STREQUAL "SCALAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + list(APPEND CMAKE_REQUIRED_LIBRARIES ${SCALAPACK_LIBRARY}) + endif() + + include(CheckFunctionExists) + + unset(_SCALAPACK_CHECK CACHE) + check_function_exists(pdpotrf_ _SCALAPACK_CHECK) + + unset(_SCALAPACK_CHECK_BLACS CACHE) + check_function_exists(Cblacs_exit _SCALAPACK_CHECK_BLACS) + + cmake_pop_check_state() +endmacro() + +if (SCALAPACK_LIBRARY STREQUAL "" OR NOT SCALAPACK_LIBRARY) + set(SCALAPACK_LIBRARY "SCALAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") +endif() + +# Dependencies +set(_DEPS "") + +find_package(LAPACK QUIET REQUIRED) +list(APPEND _DEPS "LAPACK::LAPACK") + +find_package(MPI QUIET REQUIRED) +# Enable MPI Target for all enabled languages +get_property(_ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) +foreach(_LANG ${_ENABLED_LANGUAGES}) + list(APPEND _DEPS "MPI::MPI_${_LANG}") +endforeach() + +mark_as_advanced( + SCALAPACK_LIBRARY +) + +_scalapack_check_is_working() + +### Package +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SCALAPACK DEFAULT_MSG + SCALAPACK_LIBRARY + _SCALAPACK_CHECK_BLACS + _SCALAPACK_CHECK + LAPACK_FOUND + MPI_FOUND +) + +# Remove the placeholder +if (SCALAPACK_LIBRARY STREQUAL "SCALAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") + set(SCALAPACK_LIBRARY "") +endif() + +if (SCALAPACK_FOUND) + if (NOT TARGET SCALAPACK::SCALAPACK) + add_library(SCALAPACK::SCALAPACK INTERFACE IMPORTED) + endif() + + if (SCALAPACK_LIBRARY) + target_link_libraries(SCALAPACK::SCALAPACK INTERFACE + ${SCALAPACK_LIBRARY} + ${_DEPS} + ) + endif() +endif()