Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions cmake/BuildSystem.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ The following CMake cache variables control this support:

Installed dependencies can be selected with `KokkosKernels_DIR`, `LAPACKE_ROOT`,
`LAPACKE_INCLUDE_DIRS`, `LAPACKE_LIBRARY_DIRS`, `LAPACKE_LIBRARIES`, or `MKL_DIR`.
Providers that nest their headers under `<prefix>/include/openblas/` (such as
OpenBLAS) are found automatically when the prefix is on `CMAKE_PREFIX_PATH`.
`LAPACKE_LIBRARIES` is a semicolon-separated complete link line and may contain
absolute paths, library names, imported targets, and linker items such as `-lm`.
The standard FetchContent overrides `FETCHCONTENT_SOURCE_DIR_KOKKOSKERNELS` and
Expand Down
30 changes: 12 additions & 18 deletions cmake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ endif()
# ------------------------------------------------------------------------------
# Catalyst (libcatalyst SDK and bundled Conduit parser)
# ------------------------------------------------------------------------------
if(IPPL_ENABLE_CATALYST OR IPPL_ENABLE_FEL)
if(IPPL_ENABLE_CATALYST)
enable_language(C)

if(NOT Catalyst_VERSION)
Expand All @@ -514,17 +514,16 @@ if(IPPL_ENABLE_CATALYST OR IPPL_ENABLE_FEL)
endforeach()
unset(_cat_dir_var)

# Do not mistake the package generated by an earlier FetchContent configure
# for a user-provided Catalyst installation on a subsequent configure.
# Do not mistake the package generated by an earlier FetchContent configure for a user-provided
# Catalyst installation on a subsequent configure.
set(_ippl_reuse_fetched_catalyst OFF)
set(_ippl_catalyst_dir_is_in_build_tree OFF)
if(catalyst_DIR)
cmake_path(IS_PREFIX CMAKE_BINARY_DIR "${catalyst_DIR}" NORMALIZE
_ippl_catalyst_dir_is_in_build_tree)
endif()
if(NOT Catalyst_DIR AND NOT CATALYST_DIR
AND (_ippl_catalyst_dir_is_in_build_tree
OR (IPPL_CATALYST_FETCHED AND NOT catalyst_DIR)))
if(NOT Catalyst_DIR AND NOT CATALYST_DIR AND (_ippl_catalyst_dir_is_in_build_tree
OR (IPPL_CATALYST_FETCHED AND NOT catalyst_DIR)))
set(_ippl_reuse_fetched_catalyst ON)
unset(catalyst_DIR CACHE)
unset(catalyst_FOUND)
Expand Down Expand Up @@ -556,22 +555,18 @@ if(IPPL_ENABLE_CATALYST OR IPPL_ENABLE_FEL)
set(CATALYST_WITH_EXTERNAL_CONDUIT OFF CACHE BOOL "" FORCE)
set(CATALYST_USE_MPI ON CACHE BOOL "" FORCE)

FetchContent_Declare(
catalyst
GIT_REPOSITORY "https://gitlab.kitware.com/paraview/catalyst.git"
GIT_TAG "${CATALYST_VERSION_GIT}"
DOWNLOAD_EXTRACT_TIMESTAMP ON)
FetchContent_Declare(catalyst GIT_REPOSITORY "https://gitlab.kitware.com/paraview/catalyst.git"
GIT_TAG "${CATALYST_VERSION_GIT}" DOWNLOAD_EXTRACT_TIMESTAMP ON)
FetchContent_MakeAvailable(catalyst)

if(NOT TARGET catalyst::catalyst)
message(FATAL_ERROR "Catalyst FetchContent did not provide catalyst::catalyst")
endif()

file(
STRINGS "${catalyst_SOURCE_DIR}/CMakeLists.txt" _catalyst_project_line
REGEX "^[ \t]*project\\(CATALYST VERSION [0-9]+\\.[0-9]+")
string(REGEX MATCH "VERSION[ \t]+([0-9]+\\.[0-9]+(\\.[0-9]+)?)"
_catalyst_version_match "${_catalyst_project_line}")
file(STRINGS "${catalyst_SOURCE_DIR}/CMakeLists.txt" _catalyst_project_line
REGEX "^[ \t]*project\\(CATALYST VERSION [0-9]+\\.[0-9]+")
string(REGEX MATCH "VERSION[ \t]+([0-9]+\\.[0-9]+(\\.[0-9]+)?)" _catalyst_version_match
"${_catalyst_project_line}")
if(NOT CMAKE_MATCH_1)
message(FATAL_ERROR "Could not determine the fetched Catalyst project version")
endif()
Expand All @@ -581,8 +576,7 @@ if(IPPL_ENABLE_CATALYST OR IPPL_ENABLE_FEL)
unset(_catalyst_version_match)
endif()

string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" _catalyst_major_minor
"${IPPL_CATALYST_VERSION}")
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" _catalyst_major_minor "${IPPL_CATALYST_VERSION}")
if(NOT _catalyst_major_minor)
message(FATAL_ERROR "Could not determine Catalyst's major/minor version")
endif()
Expand Down
117 changes: 78 additions & 39 deletions cmake/KokkosKernelsDependency.cmake
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Resolve host eigenanalysis independently of CUDA/HIP acceleration.
# This module is included only when IPPL_ENABLE_KOKKOS_KERNELS is enabled.
# Resolve host eigenanalysis independently of CUDA/HIP acceleration. This module is included only
# when IPPL_ENABLE_KOKKOS_KERNELS is enabled.
include(CheckCXXSourceCompiles)
include(CheckCXXSourceRuns)
include(CMakePushCheckState)
option(IPPL_FETCH_LAPACKE "Build reference LAPACKE when no installation is found" ON)
set(IPPL_HOST_LAPACK_FETCHED OFF)

set(KokkosKernels_VERSION "5.2.0" CACHE STRING "Kokkos Kernels release or git.tag/sha")
set(IPPL_KOKKOS_KERNELS_HOST "LAPACKE" CACHE STRING "Host eigenanalysis provider: LAPACKE, MKL, NONE")
set(IPPL_KOKKOS_KERNELS_HOST "LAPACKE" CACHE STRING
"Host eigenanalysis provider: LAPACKE, MKL, NONE")
set_property(CACHE IPPL_KOKKOS_KERNELS_HOST PROPERTY STRINGS LAPACKE MKL NONE)
set(IPPL_LAPACK_INTEGER_BYTES "4" CACHE STRING "Host LAPACK integer size: 4 (LP64) or 8 (ILP64)")
set_property(CACHE IPPL_LAPACK_INTEGER_BYTES PROPERTY STRINGS 4 8)
Expand All @@ -20,8 +21,8 @@ endif()

extract_git_label(KokkosKernels_VERSION _ipplKernelsGit)
if(NOT TARGET Kokkos::kokkoskernels AND NOT _ipplKernelsGit)
# Its config checks Kokkos_FOUND, whereas IPPL may have built Kokkos in-tree.
# Keep the already selected target instead of searching for another Kokkos.
# Its config checks Kokkos_FOUND, whereas IPPL may have built Kokkos in-tree. Keep the already
# selected target instead of searching for another Kokkos.
set(_ipplKokkosFound "${Kokkos_FOUND}")
set(Kokkos_FOUND TRUE)
find_package(KokkosKernels ${KokkosKernels_VERSION} CONFIG QUIET)
Expand All @@ -35,17 +36,22 @@ if(NOT TARGET Kokkos::kokkoskernels)
if(IPPL_KOKKOS_KERNELS_HOST STREQUAL "LAPACKE")
set(KokkosKernels_ENABLE_TPL_LAPACKE ON CACHE BOOL "Host LAPACKE" FORCE)
find_path(IPPL_LAPACKE_INCLUDE_DIR lapacke.h
HINTS ${LAPACKE_INCLUDE_DIRS} ${LAPACKE_ROOT}/include $ENV{LAPACKE_ROOT}/include)
HINTS ${LAPACKE_INCLUDE_DIRS} ${LAPACKE_ROOT}/include $ENV{LAPACKE_ROOT}/include
PATH_SUFFIXES openblas)
if(LAPACKE_LIBRARIES)
# An explicit link line is authoritative. Never mix it with fetched headers.
if(NOT IPPL_LAPACKE_INCLUDE_DIR)
message(FATAL_ERROR "LAPACKE_LIBRARIES was supplied but lapacke.h was not found. Set LAPACKE_INCLUDE_DIRS or LAPACKE_ROOT, or clear LAPACKE_LIBRARIES to permit the fallback.")
message(
FATAL_ERROR
"LAPACKE_LIBRARIES was supplied but lapacke.h was not found. Set LAPACKE_INCLUDE_DIRS or LAPACKE_ROOT, or clear LAPACKE_LIBRARIES to permit the fallback."
)
endif()
set(LAPACKE_INCLUDE_DIRS "${IPPL_LAPACKE_INCLUDE_DIR}")
else()
find_library(IPPL_LAPACKE_LIBRARY NAMES lapacke openblas
HINTS ${LAPACKE_LIBRARY_DIRS} ${LAPACKE_ROOT}/lib ${LAPACKE_ROOT}/lib64
$ENV{LAPACKE_ROOT}/lib $ENV{LAPACKE_ROOT}/lib64)
find_library(
IPPL_LAPACKE_LIBRARY NAMES lapacke openblas
HINTS ${LAPACKE_LIBRARY_DIRS} ${LAPACKE_ROOT}/lib ${LAPACKE_ROOT}/lib64
$ENV{LAPACKE_ROOT}/lib $ENV{LAPACKE_ROOT}/lib64)
if(IPPL_LAPACKE_INCLUDE_DIR AND IPPL_LAPACKE_LIBRARY)
set(BLA_SIZEOF_INTEGER "${IPPL_LAPACK_INTEGER_BYTES}")
find_package(LAPACK QUIET)
Expand All @@ -57,7 +63,10 @@ if(NOT TARGET Kokkos::kokkoskernels)
include(FetchHostLapack)
ippl_fetch_host_lapack()
else()
message(FATAL_ERROR "Host LAPACKE was not found and IPPL_FETCH_LAPACKE=OFF. Set LAPACKE_ROOT or supply LAPACKE_INCLUDE_DIRS and LAPACKE_LIBRARIES.")
message(
FATAL_ERROR
"Host LAPACKE was not found and IPPL_FETCH_LAPACKE=OFF. Set LAPACKE_ROOT or supply LAPACKE_INCLUDE_DIRS and LAPACKE_LIBRARIES."
)
endif()
endif()
elseif(IPPL_KOKKOS_KERNELS_HOST STREQUAL "MKL")
Expand All @@ -72,25 +81,25 @@ if(NOT TARGET Kokkos::kokkoskernels)

foreach(_backend CUBLAS CUSOLVER CUSPARSE ROCBLAS ROCSOLVER ROCSPARSE)
set(_enabled OFF)
if(("CUDA" IN_LIST IPPL_PLATFORMS AND _backend MATCHES "^CU") OR
("HIP" IN_LIST IPPL_PLATFORMS AND _backend MATCHES "^ROC"))
if(("CUDA" IN_LIST IPPL_PLATFORMS AND _backend MATCHES "^CU") OR ("HIP" IN_LIST IPPL_PLATFORMS
AND _backend MATCHES "^ROC"))
set(_enabled ON)
endif()
set(KokkosKernels_ENABLE_TPL_${_backend} ${_enabled} CACHE BOOL "IPPL GPU linear algebra backend" FORCE)
set(KokkosKernels_ENABLE_TPL_${_backend} ${_enabled}
CACHE BOOL "IPPL GPU linear algebra backend" FORCE)
endforeach()
# Avoid the considerable ETI build cost by instantiating only kernels used by IPPL.
set(KokkosKernels_ADD_DEFAULT_ETI OFF CACHE BOOL "Preinstantiate default Kokkos Kernels types")
set(KokkosKernels_ENABLE_SUPERNODAL_SPTRSV OFF CACHE BOOL "Supernodal solver requires LayoutLeft ETI")
set(KokkosKernels_ENABLE_SUPERNODAL_SPTRSV OFF CACHE BOOL
"Supernodal solver requires LayoutLeft ETI")
if(NOT _ipplKernelsGit)
set(_ipplKernelsGit "${KokkosKernels_VERSION}")
endif()
FetchContent_Declare(KokkosKernels
GIT_REPOSITORY https://github.com/kokkos/kokkos-kernels.git
GIT_TAG ${_ipplKernelsGit})
# Upstream uses pre-CMP0126 cache semantics and otherwise replaces inherited
# discovery results with empty cache defaults. Seed them only for its configure,
# then restore the user's cache so automatic fallback values do not become
# authoritative user overrides on the next configure.
FetchContent_Declare(KokkosKernels GIT_REPOSITORY https://github.com/kokkos/kokkos-kernels.git
GIT_TAG ${_ipplKernelsGit})
# Upstream uses pre-CMP0126 cache semantics and otherwise replaces inherited discovery results
# with empty cache defaults. Seed them only for its configure, then restore the user's cache so
# automatic fallback values do not become authoritative user overrides on the next configure.
foreach(_variable LAPACKE_INCLUDE_DIRS LAPACKE_LIBRARIES)
get_property(_saved${_variable} CACHE ${_variable} PROPERTY VALUE)
get_property(_had${_variable} CACHE ${_variable} PROPERTY TYPE SET)
Expand All @@ -105,17 +114,17 @@ if(NOT TARGET Kokkos::kokkoskernels)
endif()
endforeach()
# Upstream installs an export but does not provide a build-tree export.
export(EXPORT KokkosKernelsTargets
FILE "${kokkoskernels_BINARY_DIR}/KokkosKernelsTargets.cmake" NAMESPACE Kokkos::)
export(EXPORT KokkosKernelsTargets FILE "${kokkoskernels_BINARY_DIR}/KokkosKernelsTargets.cmake"
NAMESPACE Kokkos::)
set(IPPL_KOKKOS_KERNELS_PACKAGE_HINT "${kokkoskernels_BINARY_DIR}")
set(IPPL_KOKKOS_KERNELS_FETCHED ON)
else()
set(IPPL_KOKKOS_KERNELS_PACKAGE_HINT "${KokkosKernels_DIR}")
set(IPPL_KOKKOS_KERNELS_FETCHED OFF)
endif()

# Find the actual generated configuration header: inspect the target, not the
# user's cache options, which cannot enable features in an installed package.
# Find the actual generated configuration header: inspect the target, not the user's cache options,
# which cannot enable features in an installed package.
get_target_property(_kernelIncludes Kokkos::kokkoskernels INTERFACE_INCLUDE_DIRECTORIES)
set(_kernelConfig)
foreach(_include IN LISTS _kernelIncludes)
Expand All @@ -130,31 +139,47 @@ if(NOT _kernelConfig)
message(FATAL_ERROR "Cannot locate KokkosKernels_config.h on Kokkos::kokkoskernels")
endif()
file(READ "${_kernelConfig}" _kernelConfiguration)
foreach(_backend IN ITEMS LAPACKE MKL CUBLAS CUSOLVER CUSPARSE ROCBLAS ROCSOLVER ROCSPARSE)
foreach(
_backend IN
ITEMS LAPACKE
MKL
CUBLAS
CUSOLVER
CUSPARSE
ROCBLAS
ROCSOLVER
ROCSPARSE)
set(_has${_backend} OFF)
if(_kernelConfiguration MATCHES "#define KOKKOSKERNELS_ENABLE_TPL_${_backend}([ \t\r\n]|$)")
set(_has${_backend} ON)
endif()
endforeach()
set(IPPL_KOKKOS_KERNELS_NEEDS_MKL ${_hasMKL})
if(_hasMKL)
# Modern upstream MKL exports reference MKL::MKL, including when host
# eigenanalysis was disabled in IPPL but the external package still uses MKL.
# Modern upstream MKL exports reference MKL::MKL, including when host eigenanalysis was disabled
# in IPPL but the external package still uses MKL.
find_package(MKL CONFIG REQUIRED)
endif()
foreach(_platform CUDA HIP)
if(_platform IN_LIST IPPL_PLATFORMS)
if((_platform STREQUAL "CUDA" AND (NOT _hasCUBLAS OR NOT _hasCUSOLVER OR NOT _hasCUSPARSE)) OR
(_platform STREQUAL "HIP" AND (NOT _hasROCBLAS OR NOT _hasROCSOLVER OR NOT _hasROCSPARSE)))
message(FATAL_ERROR "Selected Kokkos Kernels lacks the required ${_platform} BLAS/solver TPLs. Rebuild it with the matching backend.")
if((_platform STREQUAL "CUDA" AND (NOT _hasCUBLAS OR NOT _hasCUSOLVER OR NOT _hasCUSPARSE))
OR (_platform STREQUAL "HIP" AND (NOT _hasROCBLAS OR NOT _hasROCSOLVER OR NOT _hasROCSPARSE)
))
message(
FATAL_ERROR
"Selected Kokkos Kernels lacks the required ${_platform} BLAS/solver TPLs. Rebuild it with the matching backend."
)
endif()
endif()
endforeach()

set(IPPL_KOKKOS_KERNELS_EIGENANALYSIS OFF)
if(NOT IPPL_KOKKOS_KERNELS_HOST STREQUAL "NONE")
if(NOT _has${IPPL_KOKKOS_KERNELS_HOST})
message(FATAL_ERROR "Selected Kokkos Kernels lacks ${IPPL_KOKKOS_KERNELS_HOST}. Rebuild it with this host TPL, or select IPPL_KOKKOS_KERNELS_HOST=NONE.")
message(
FATAL_ERROR
"Selected Kokkos Kernels lacks ${IPPL_KOKKOS_KERNELS_HOST}. Rebuild it with this host TPL, or select IPPL_KOKKOS_KERNELS_HOST=NONE."
)
endif()
set(_integerDefinition)
if(IPPL_LAPACK_INTEGER_BYTES STREQUAL "8")
Expand All @@ -181,7 +206,8 @@ if(NOT IPPL_KOKKOS_KERNELS_HOST STREQUAL "NONE")
get_target_property(_hostIncludes LAPACKE INTERFACE_INCLUDE_DIRECTORIES)
set_target_properties(ippl_lapacke_probe PROPERTIES INTERFACE_LINK_LIBRARIES "${_hostLinks}")
if(_hostIncludes)
set_target_properties(ippl_lapacke_probe PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_hostIncludes}")
set_target_properties(ippl_lapacke_probe PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
"${_hostIncludes}")
endif()
set(CMAKE_REQUIRED_LIBRARIES ippl_lapacke_probe)
else()
Expand All @@ -196,7 +222,8 @@ if(NOT IPPL_KOKKOS_KERNELS_HOST STREQUAL "NONE")
endif()
# Recheck after provider/path changes rather than retaining a stale success.
unset(IPPL_HOST_EIGEN_LINKS CACHE)
set(_hostEigenProbe "
set(_hostEigenProbe
"
#include <${_header}>
#include <cmath>
static_assert(sizeof(lapack_int) == ${IPPL_LAPACK_INTEGER_BYTES}, \"LAPACK integer ABI mismatch\");
Expand All @@ -215,15 +242,27 @@ if(NOT IPPL_KOKKOS_KERNELS_HOST STREQUAL "NONE")
unset(IPPL_HOST_EIGEN_RUNS CACHE)
check_cxx_source_runs("${_hostEigenProbe}" IPPL_HOST_EIGEN_RUNS)
if(NOT IPPL_HOST_EIGEN_RUNS)
message(FATAL_ERROR "Host LAPACKE linked but failed the eigenvalue/ABI smoke test. Check the selected libraries and integer interface.")
message(
FATAL_ERROR
"Host LAPACKE linked but failed the eigenvalue/ABI smoke test. Check the selected libraries and integer interface."
)
endif()
elseif(CMAKE_CROSSCOMPILING)
message(STATUS "Cross-compiling: host LAPACKE compile/link checked; runtime ABI validation deferred to unit tests")
message(
STATUS
"Cross-compiling: host LAPACKE compile/link checked; runtime ABI validation deferred to unit tests"
)
endif()
cmake_pop_check_state()
if(NOT IPPL_HOST_EIGEN_LINKS)
message(FATAL_ERROR "Host LAPACKE eigenanalysis failed to compile/link. Check matching headers, LP64/ILP64 libraries, and all static dependencies (including Fortran runtime). See CMake configure log.")
message(
FATAL_ERROR
"Host LAPACKE eigenanalysis failed to compile/link. Check matching headers, LP64/ILP64 libraries, and all static dependencies (including Fortran runtime). See CMake configure log."
)
endif()
set(IPPL_KOKKOS_KERNELS_EIGENANALYSIS ON)
endif()
message(STATUS "IPPL Kokkos Kernels: host=${IPPL_KOKKOS_KERNELS_HOST}, eigenanalysis=${IPPL_KOKKOS_KERNELS_EIGENANALYSIS}")
message(
STATUS
"IPPL Kokkos Kernels: host=${IPPL_KOKKOS_KERNELS_HOST}, eigenanalysis=${IPPL_KOKKOS_KERNELS_EIGENANALYSIS}"
)
8 changes: 5 additions & 3 deletions demos/fel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ add_custom_command(
add_custom_target(ippl_fel_config DEPENDS "${IPPL_FEL_CONFIG_BUILD}")
add_dependencies(FreeElectronLaser ippl_fel_config)

target_link_libraries(
FreeElectronLaser
PRIVATE IPPL::ippl catalyst::catalyst)
target_link_libraries(FreeElectronLaser PRIVATE IPPL::ippl)

if(IPPL_ENABLE_CATALYST)
target_link_libraries(FreeElectronLaser PRIVATE catalyst::catalyst)
endif()

target_include_directories(FreeElectronLaser PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(FreeElectronLaser SYSTEM PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/stb)
Loading
Loading