Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake: Use LAPACK imported target #542

Merged
merged 26 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dc2cf8d
use LAPACK imported target
gardner48 Jun 21, 2024
fa151eb
add install guide to Makefile
gardner48 Jun 21, 2024
6967545
update template
gardner48 Jun 21, 2024
49ce6dd
remove LAPACK_WORKS from post build option
gardner48 Jun 22, 2024
635d12f
trigger formatting
gardner48 Jul 14, 2024
d3a7c31
apply formatting
gardner48 Jul 15, 2024
827aae6
fix list formatting
gardner48 Jul 15, 2024
033f5cc
remove run on push
gardner48 Jul 15, 2024
b7e2a2f
set BLAS_LIBRARIES for Jenkins CI
gardner48 Jul 16, 2024
074e7d6
Merge branch 'develop' into cmake/lapack-target
gardner48 Jul 17, 2024
7e982f3
workaround bug in older CMake versions
gardner48 Jul 18, 2024
1b3bcf2
apply formatting
gardner48 Jul 18, 2024
c370e2f
work around CMake bug with LAPACK::LAPACK not including BLAS::BLAS
gardner48 Jul 18, 2024
51cbea8
apply formatting
gardner48 Jul 18, 2024
f82145a
Merge branch 'develop' into cmake/lapack-target
balos1 Aug 5, 2024
b54a400
Merge branch 'develop' into cmake/lapack-target
gardner48 Aug 6, 2024
b2c0861
Merge branch 'develop' into cmake/lapack-target
gardner48 Sep 11, 2024
a27a072
Merge branch 'develop' into cmake/lapack-target
gardner48 Sep 11, 2024
9703924
Merge branch 'develop' into cmake/lapack-target
gardner48 Sep 13, 2024
92e184b
fix SUNDIALSConfig finding blas/lapack
gardner48 Sep 13, 2024
979c7ab
simplify cmake workaround
gardner48 Sep 13, 2024
79d8d00
simplify getting LAPACK_LIBRARY_DIR
gardner48 Sep 13, 2024
c7f11c3
fix typo
gardner48 Sep 13, 2024
a5bfd00
update install docs
gardner48 Sep 13, 2024
a81d51a
update changelog
gardner48 Sep 14, 2024
332ad98
Merge branch 'develop' into cmake/lapack-target
gardner48 Sep 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ backends with Trilinos. As such, Trilinos 14 or newer is required and the

Example programs using *hypre* have been updated to support v2.20 and newer.

The build system has been updated to utilize the CMake LAPACK imported target
which should ease building SUNDIALS with LAPACK libraries that require setting
specific linker flags e.g., MKL.

### Bug Fixes

Fixed `ARKodeResize` not using the default `hscale` when an argument of `0` was
Expand Down
10 changes: 10 additions & 0 deletions cmake/SUNDIALSConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ if("@ENABLE_KOKKOS_KERNELS@" AND NOT TARGET Kokkos::kokkoskernels)
find_dependency(KokkosKernels PATHS "@KokkosKernels_DIR@")
endif()

if("@ENABLE_LAPACK@" AND NOT TARGET LAPACK::LAPACK)
# For some reason find_dependency does not find the libraries if the variables
# below are internal rather than CACHE variables
set(BLAS_LIBRARIES "@BLAS_LIBRARIES@" CACHE "FILEPATH" "BLAS libraries")
set(BLAS_LINKER_FLAGS "@BLAS_LINKER_FLAGS@" CACHE "STRING" "BLAS linker flags")
set(LAPACK_LIBRARIES "@LAPACK_LIBRARIES@" CACHE "FILEPATH" "LAPACK libraries")
set(LAPACK_LINKER_FLAGS "@LAPACK_LINKER_FLAGS@" CACHE "STRING" "LAPACK linker flags")
find_dependency(LAPACK)
endif()

if("@ENABLE_PETSC@" AND NOT TARGET SUNDIALS::PETSC)
add_library(SUNDIALS::PETSC INTERFACE IMPORTED)
target_link_libraries(SUNDIALS::PETSC INTERFACE "@PETSC_LIBRARIES@")
Expand Down
4 changes: 2 additions & 2 deletions cmake/SundialsBuildOptionsPost.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,14 @@ list(APPEND SUNDIALS_BUILD_LIST "BUILD_SUNLINSOL_KOKKOSDENSE")
sundials_option(
BUILD_SUNLINSOL_LAPACKBAND BOOL
"Build the SUNLINSOL_LAPACKBAND module (requires LAPACK)" ON
DEPENDS_ON ENABLE_LAPACK LAPACK_WORKS
DEPENDS_ON ENABLE_LAPACK
ADVANCED)
list(APPEND SUNDIALS_BUILD_LIST "BUILD_SUNLINSOL_LAPACKBAND")

sundials_option(
BUILD_SUNLINSOL_LAPACKDENSE BOOL
"Build the SUNLINSOL_LAPACKDENSE module (requires LAPACK)" ON
DEPENDS_ON ENABLE_LAPACK LAPACK_WORKS
DEPENDS_ON ENABLE_LAPACK
ADVANCED)
list(APPEND SUNDIALS_BUILD_LIST "BUILD_SUNLINSOL_LAPACKDENSE")

Expand Down
125 changes: 43 additions & 82 deletions cmake/tpl/SundialsLapack.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,28 @@
# Section 1: Include guard
# -----------------------------------------------------------------------------

if(NOT DEFINED SUNDIALS_LAPACK_INCLUDED)
set(SUNDIALS_LAPACK_INCLUDED)
else()
return()
endif()
include_guard(GLOBAL)

# -----------------------------------------------------------------------------
# Section 2: Check to make sure options are compatible
# -----------------------------------------------------------------------------

# LAPACK does not support extended precision
if(ENABLE_LAPACK AND SUNDIALS_PRECISION MATCHES "EXTENDED")
print_error("LAPACK is not compatible with ${SUNDIALS_PRECISION} precision")
message(
FATAL_ERROR "LAPACK is not compatible with ${SUNDIALS_PRECISION} precision")
endif()

# -----------------------------------------------------------------------------
# Section 3: Find the TPL
# -----------------------------------------------------------------------------

# If LAPACK libraries are undefined, try to find them.
if(NOT LAPACK_LIBRARIES)
find_package(LAPACK REQUIRED)
endif()
find_package(LAPACK REQUIRED)

# If we have the LAPACK libraries, display progress message.
if(LAPACK_LIBRARIES)
message(STATUS "Looking for LAPACK libraries... OK")
set(LAPACK_FOUND TRUE)
else()
message(STATUS "Looking for LAPACK libraries... FAILED")
set(LAPACK_FOUND FALSE)
endif()

message(STATUS "LAPACK_LIBRARIES: ${LAPACK_LIBRARIES}")
# get path to LAPACK library to use in generated makefiles for examples, if
# LAPACK_LIBRARIES contains multiple items only use the path of the first entry
list(GET LAPACK_LIBRARIES 0 TMP_LAPACK_LIBRARIES)
get_filename_component(LAPACK_LIBRARY_DIR ${TMP_LAPACK_LIBRARIES} PATH)

# -----------------------------------------------------------------------------
# Section 4: Test the TPL
Expand Down Expand Up @@ -302,33 +290,17 @@ if(NEED_FORTRAN_NAME_MANGLING)

endif()

# If we have the LAPACK libraries, determine if they work.
if(LAPACK_LIBRARIES AND (NOT LAPACK_WORKS))
# Create the LapackTest directory
set(LapackTest_DIR ${PROJECT_BINARY_DIR}/LapackTest)
file(MAKE_DIRECTORY ${LapackTest_DIR})
# Try building a simple test
if(NOT LAPACK_WORKS)

# Create a CMakeLists.txt file
file(
WRITE ${LapackTest_DIR}/CMakeLists.txt
"CMAKE_MINIMUM_REQUIRED(VERSION ${CMAKE_VERSION})\n"
"PROJECT(ltest C)\n"
"SET(CMAKE_VERBOSE_MAKEFILE ON)\n"
"SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n"
"SET(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n"
"SET(CMAKE_C_STANDARD \"${CMAKE_C_STANDARD}\")\n"
"SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n"
"SET(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n"
"SET(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n"
"SET(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n"
"SET(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n"
"ADD_EXECUTABLE(ltest ltest.c)\n"
"TARGET_LINK_LIBRARIES(ltest ${LAPACK_LIBRARIES})\n")

# Create a C source file which calls a Blas function (dcopy) and an Lapack
# function (dgetrf)
message(CHECK_START "Testing LAPACK")

# Create the test directory
set(LAPACK_TEST_DIR ${PROJECT_BINARY_DIR}/LAPACK_TEST)

# Create a C source file calling a BLAS (dcopy) and LAPACK (dgetrf) function
file(
WRITE ${LapackTest_DIR}/ltest.c
WRITE ${LAPACK_TEST_DIR}/test.c
"${LAPACK_MANGLE_MACRO1}\n"
"#define dcopy_f77 SUNDIALS_LAPACK_FUNC(dcopy, DCOPY)\n"
"#define dgetrf_f77 SUNDIALS_LAPACK_FUNC(dgetrf, DGETRF)\n"
Expand All @@ -340,49 +312,38 @@ if(LAPACK_LIBRARIES AND (NOT LAPACK_WORKS))
"double y=1.0;\n"
"dcopy_f77(&n, &x, &n, &y, &n);\n"
"dgetrf_f77(&n, &n, &x, &n, &n, &n);\n"
"return(0);\n"
"return 0;\n"
"}\n")

# Attempt to build and link the "ltest" executable
# Workaround bug in older versions of CMake where the BLAS::BLAS target, which
# LAPACK::LAPACK depends on, is not defined in the file
# ${LAPACK_TEST_DIR}/CMakeFiles/CMakeTmp/<random_name>Targets.cmake created by
# try_compile
set(_lapack_targets LAPACK::LAPACK)
if(CMAKE_VERSION VERSION_LESS 3.20)
list(APPEND _lapack_targets BLAS::BLAS)
endif()

# Attempt to build and link the test executable, pass --debug-trycompile to
# the cmake command to save build files for debugging
try_compile(
COMPILE_OK ${LapackTest_DIR}
${LapackTest_DIR} ltest
COMPILE_OK ${LAPACK_TEST_DIR}
${LAPACK_TEST_DIR}/test.c
LINK_LIBRARIES ${_lapack_targets}
OUTPUT_VARIABLE COMPILE_OUTPUT)

# To ensure we do not use stuff from the previous attempts, we must remove the
# CMakeFiles directory.
file(REMOVE_RECURSE ${LapackTest_DIR}/CMakeFiles)

# Process test result
# Check the result
if(COMPILE_OK)
message(STATUS "Checking if LAPACK works with SUNDIALS... OK")
set(LAPACK_WORKS
TRUE
CACHE BOOL "LAPACK works with SUNDIALS as configured" FORCE)

# get path to LAPACK library to use in generated makefiles for examples, if
# LAPACK_LIBRARIES contains multiple items only use the path of the first
# entry
list(LENGTH LAPACK_LIBRARIES len)
if(len EQUAL 1)
get_filename_component(LAPACK_LIBRARY_DIR ${LAPACK_LIBRARIES} PATH)
else()
list(GET LAPACK_LIBRARIES 0 TMP_LAPACK_LIBRARIES)
get_filename_component(LAPACK_LIBRARY_DIR ${TMP_LAPACK_LIBRARIES} PATH)
endif()
else(COMPILE_OK)
set(LAPACK_WORKS
FALSE
CACHE BOOL "LAPACK does not work with SUNDIALS as configured" FORCE)
message(STATUS "Checking if LAPACK works with SUNDIALS... FAILED")
message(STATUS "Check output: ")
message("${COMPILE_OUTPUT}")
message(FATAL_ERROR "SUNDIALS interface to LAPACK is not functional.")
message(CHECK_PASS "success")
else()
message(CHECK_FAIL "failed")
file(WRITE ${LAPACK_TEST_DIR}/compile.out "${COMPILE_OUTPUT}")
message(
FATAL_ERROR
"Could not compile LAPACK test. Check output in ${LAPACK_TEST_DIR}/compile.out"
)
endif()

elseif(LAPACK_LIBRARIES AND LAPACK_WORKS)
message(
STATUS
"Skipped LAPACK tests, assuming LAPACK works with SUNDIALS. Set LAPACK_WORKS=FALSE to (re)run compatibility test."
)
else()
message(STATUS "Skipped LAPACK test. Set LAPACK_WORKS=FALSE to test.")
endif()
52 changes: 23 additions & 29 deletions cmake/tpl/SundialsTPL.cmake.template
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@
# Section 1: Include guard
# -----------------------------------------------------------------------------

if(NOT DEFINED SUNDIALS_<TPL>_INCLUDED)
set(SUNDIALS_<TPL>_INCLUDED)
else()
return()
endif()
include_guard(GLOBAL)

# -----------------------------------------------------------------------------
# Section 2: Check to make sure options are compatible
Expand All @@ -46,38 +42,36 @@ find_package(<TPL> REQUIRED)
# Section 4: Test the TPL
# -----------------------------------------------------------------------------

if(<TPL>_FOUND AND (NOT <TPL>_WORKS))
# Do any checks which don't require compilation first.
# Do any checks which don't require compilation first.

# Create the <TPL>_TEST directory
set(<TPL>_TEST_DIR ${PROJECT_BINARY_DIR}/<TPL>_TEST)
file(MAKE_DIRECTORY ${<TPL>_TEST_DIR})
# Try building a simple test
if(NOT <TPL>_WORKS)

# Create a CMakeLists.txt file
file(WRITE ${<TPL>_TEST_DIR}/CMakeLists.txt "")
message(CHECK_START "Testing <TPL>")
gardner48 marked this conversation as resolved.
Show resolved Hide resolved

# Create a C source file
file(WRITE ${<TPL>_TEST_DIR}/ltest.c "")
# Create the test directory
set(<TPL>_TEST_DIR ${PROJECT_BINARY_DIR}/<TPL>_TEST)

# To ensure we do not use stuff from the previous attempts,
# we must remove the CMakeFiles directory.
file(REMOVE_RECURSE ${<TPL>_TEST_DIR}/CMakeFiles)
# Create a C source file
file(WRITE ${<TPL>_TEST_DIR}/test.c
"int main(void) {\n"
"return 0;\n"
"}\n")

# Attempt to build and link the "ltest" executable
try_compile(COMPILE_OK ${<TPL>_TEST_DIR} ${<TPL>_TEST_DIR} ltest
OUTPUT_VARIABLE COMPILE_OUTPUT)
# Attempt to build and link the test executable, pass --debug-trycompile to
# the cmake command to save build files for debugging
try_compile(COMPILE_OK ${<TPL>_TEST_DIR} ${<TPL>_TEST_DIR}/test.c
LINK_LIBRARIES <TPL target> OUTPUT_VARIABLE COMPILE_OUTPUT)

# Process test result
# Check the result
if(COMPILE_OK)
message(STATUS "Checking if <TPL> works with SUNDIALS... OK")
set(<TPL>_WORKS TRUE CACHE BOOL "<TPL> works with SUNDIALS as configured" FORCE)
message(CHECK_PASS "success")
else()
message(STATUS "Checking if <TPL> works with SUNDIALS... FAILED")
message(STATUS "Check output: ")
message("${COMPILE_OUTPUT}")
message(FATAL_ERROR "SUNDIALS interface to <TPL> is not functional.")
message(CHECK_FAIL "failed")
file(WRITE ${<TPL>_TEST_DIR}/compile.out "${COMPILE_OUTPUT}")
message(FATAL_ERROR "Could not compile <TPL> test. Check output in ${<TPL>_TEST_DIR}/compile.out")
endif()

elseif(<TPL>_FOUND AND <TPL>_WORKS)
message(STATUS "Skipped <TPL> tests, assuming <TPL> works with SUNDIALS.")
else()
message(STATUS "Skipped <TPL> test. Set <TPL>_WORKS=FALSE to test.")
endif()
4 changes: 2 additions & 2 deletions doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ DIRS = arkode/guide arkode/examples \
kinsol/guide

# prefix with desired command to create unique dependencies/targets
LATEXDIRS = $(DIRS:%=latexpdf-%)
LATEXDIRS = $(DIRS:%=latexpdf-%) latexpdf-install_guide
HTMLDIRS = $(DIRS:%=html-%) html-superbuild
CLEANDIRS = $(DIRS:%=clean-%) clean-superbuild
CLEANDIRS = $(DIRS:%=clean-%) clean-superbuild clean-install_guide

latexpdf: $(LATEXDIRS)
$(LATEXDIRS):
Expand Down
4 changes: 4 additions & 0 deletions doc/shared/RecentChanges.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ backends with Trilinos. As such, Trilinos 14 or newer is required and the

Example programs using *hypre* have been updated to support v2.20 and newer.

The build system has been updated to utilize the CMake LAPACK imported target
which should ease building SUNDIALS with LAPACK libraries that require setting
specific linker flags e.g., MKL.

**Bug Fixes**

Fixed c:func:`ARKodeResize` not using the default ``hscale`` when an argument of
Expand Down
42 changes: 28 additions & 14 deletions doc/shared/sundials/Install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -776,15 +776,29 @@ illustration only.
options. See additional information on building with
LAPACK enabled in :numref:`Installation.CMake.ExternalLibraries`.

.. cmakeoption:: BLAS_LIBRARIES

BLAS libraries

Default: none (CMake will try to find a BLAS installation)

.. cmakeoption:: BLAS_LINKER_FLAGS

BLAS required linker flags

Default: none (CMake will try to determine the necessary flags)

.. cmakeoption:: LAPACK_LIBRARIES

LAPACK (and BLAS) libraries
LAPACK libraries

Default: none (CMake will try to find a LAPACK installation)

.. cmakeoption:: LAPACK_LINKER_FLAGS

Default: ``/usr/lib/liblapack.so;/usr/lib/libblas.so``
LAPACK required linker flags

.. note:: CMake will search for libraries in your
``LD_LIBRARY_PATH`` prior to searching default system
paths.
Default: none (CMake will try to determine the necessary flags)

.. cmakeoption:: ENABLE_MAGMA

Expand Down Expand Up @@ -1334,21 +1348,21 @@ path to the root of the Kokkos-Kernels installation in
Building with LAPACK
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To enable LAPACK, set the ``ENABLE_LAPACK`` option to ``ON``.
If the directory containing the LAPACK library is in the
``LD_LIBRARY_PATH`` environment variable, CMake will set the
``LAPACK_LIBRARIES`` variable accordingly, otherwise CMake will
attempt to find the LAPACK library in standard system locations. To
explicitly tell CMake what library to use, the ``LAPACK_LIBRARIES``
variable can be set to the desired libraries required for LAPACK.
To enable LAPACK, set the :cmakeop:`ENABLE_LAPACK` option to ``ON``. CMake will
attempt to find BLAS and LAPACK installations on the system and set the
variables :cmakeop:`BLAS_LIBRARIES`, :cmakeop:`BLAS_LINKER_FLAGS`,
:cmakeop:`LAPACK_LIBRARIES`, and :cmakeop:`LAPACK_LINKER_FLAGS`. To explicitly
specify the LAPACK library to build with, manually set the aforementioned
variables to the desired values when configuring the build.

.. code-block:: bash

% cmake \
> -DCMAKE_INSTALL_PREFIX=/home/myname/sundials/instdir \
> -DEXAMPLES_INSTALL_PATH=/home/myname/sundials/instdir/examples \
> -DENABLE_LAPACK=ON \
> -DLAPACK_LIBRARIES=/mylapackpath/lib/libblas.so;/mylapackpath/lib/liblapack.so \
> -DBLAS_LIBRARIES=/mylapackpath/lib/libblas.so \
> -DLAPACK_LIBRARIES=/mylapackpath/lib/liblapack.so \
> /home/myname/sundials/srcdir

% make install
Expand All @@ -1362,7 +1376,7 @@ variable can be set to the desired libraries required for LAPACK.
these options in earlier versions of SUNDIALS were ``lower`` and ``one``,
respectively.

SUNDIALS has been tested with OpenBLAS 0.3.18.
SUNDIALS has been tested with OpenBLAS 0.3.27.


.. _Installation.CMake.ExternalLibraries.KLU:
Expand Down
3 changes: 0 additions & 3 deletions examples/arkode/F2003_serial/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,6 @@ if(BUILD_SUNLINSOL_LAPACKDENSE)
set(SUNLINSOLLAPACK_LIBS sundials_sunlinsollapackdense
sundials_fsunlinsollapackdense_mod)

# LAPACK libraries
list(APPEND SUNLINSOLLAPACK_LIBS ${LAPACK_LIBRARIES})

foreach(example_tuple ${FARKODE_examples_LAPACK})

# parse the example tuple
Expand Down
Loading
Loading