1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
|
cmake_minimum_required(VERSION 3.18 FATAL_ERROR) # 3.18 for C++17
project(SpFFT LANGUAGES CXX VERSION 1.1.1)
set(SPFFT_SO_VERSION 1)
set(SPFFT_VERSION ${PROJECT_VERSION})
# allow {module}_ROOT variables to be set
if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()
# Initialize CMAKE_CUDA_ARCHITECTURES through nvcc if possible
if(POLICY CMP0104)
cmake_policy(SET CMP0104 NEW)
endif()
# set default build type to RELEASE
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo"
)
endif()
# set language and standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_HIP_STANDARD 17)
#add local module path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/modules)
include(CMakeDependentOption)
# Options
option(SPFFT_STATIC "Compile as static library" OFF)
option(SPFFT_OMP "Compile with OpenMP support" ON)
option(SPFFT_MPI "Compile with MPI support" ON)
option(SPFFT_GPU_DIRECT "Compile with GPU direct (GPU aware MPI) support." OFF)
option(SPFFT_BUILD_TESTS "Build tests" OFF)
option(SPFFT_SINGLE_PRECISION "Enable single precision support" OFF)
option(SPFFT_INSTALL "Enable CMake install commands" ON)
option(SPFFT_FORTRAN "Compile fortran module" OFF)
option(SPFFT_BUNDLED_LIBS "Use bundled libraries for building tests" ON)
cmake_dependent_option(SPFFT_BUNDLED_GOOGLETEST "Use bundled googletest lib" ON "SPFFT_BUNDLED_LIBS" OFF)
cmake_dependent_option(SPFFT_BUNDLED_JSON "Use bundled json lib" ON "SPFFT_BUNDLED_LIBS" OFF)
cmake_dependent_option(SPFFT_BUNDLED_CLI11 "Use bundled CLI11 lib" ON "SPFFT_BUNDLED_LIBS" OFF)
set(SPFFT_GPU_BACKEND "OFF" CACHE STRING "GPU backend")
set_property(CACHE SPFFT_GPU_BACKEND PROPERTY STRINGS
"OFF" "CUDA" "ROCM"
)
set(SPFFT_FFTW_LIB "AUTO" CACHE STRING "Library providing a FFTW interface")
set_property(CACHE SPFFT_FFTW_LIB PROPERTY STRINGS
"AUTO" "FFTW" "MKL" "ARMPL"
)
# Get GNU standard install prefixes
include(GNUInstallDirs)
# set preferred library type
if (SPFFT_STATIC)
# prefer static over dynamic libraries with the find_library() command by changing the order
set(CMAKE_FIND_LIBRARY_SUFFIXES_SAVE ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .tbd .dylib .so)
elseif(UNIX)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .so)
endif()
set(SPFFT_LIBRARY_TYPE STATIC)
else()
set(SPFFT_LIBRARY_TYPE SHARED)
endif()
set(SPFFT_EXTERNAL_LIBS)
set(SPFFT_INCLUDE_DIRS)
set(SPFFT_EXTERNAL_INCLUDE_DIRS)
set(SPFFT_EXTERNAL_PKG_PACKAGES)
# Options combination check
set(SPFFT_CUDA OFF)
set(SPFFT_ROCM OFF)
if(SPFFT_GPU_BACKEND)
if(SPFFT_GPU_BACKEND STREQUAL "CUDA")
set(SPFFT_CUDA ON)
elseif(SPFFT_GPU_BACKEND STREQUAL "ROCM")
set(SPFFT_ROCM ON)
else()
message(FATAL_ERROR "Invalid GPU backend option")
endif()
endif()
mark_as_advanced(SPFFT_CUDA SPFFT_ROCM)
# Fortran
if(SPFFT_FORTRAN)
enable_language(Fortran)
endif()
# CUDA
if(SPFFT_CUDA)
enable_language(CUDA)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
find_package(CUDAToolkit REQUIRED)
else()
find_library(CUDA_CUDART_LIBRARY cudart PATHS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
find_library(CUDA_CUFFT_LIBRARY cufft PATHS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
if(NOT TARGET CUDA::cudart)
add_library(CUDA::cudart INTERFACE IMPORTED)
endif()
set_property(TARGET CUDA::cudart PROPERTY INTERFACE_LINK_LIBRARIES ${CUDA_CUDART_LIBRARY})
set_property(TARGET CUDA::cudart PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
if(NOT TARGET CUDA::cufft)
add_library(CUDA::cufft INTERFACE IMPORTED)
endif()
set_property(TARGET CUDA::cufft PROPERTY INTERFACE_LINK_LIBRARIES ${CUDA_CUFFT_LIBRARY})
set_property(TARGET CUDA::cufft PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
endif()
list(APPEND SPFFT_EXTERNAL_LIBS CUDA::cudart CUDA::cufft)
endif()
# ROCM
if(SPFFT_ROCM)
cmake_minimum_required(VERSION 3.21 FATAL_ERROR) # hip support only added in 3.21
enable_language(HIP)
find_package(hip CONFIG REQUIRED)
find_package(rocfft CONFIG REQUIRED)
find_package(hipfft CONFIG) # hipfft within rocfft is deprecated. Use separate hipfft if available (not required).
if(hipfft_FOUND)
# Issue with rocm 4.1.0: Symlink to rocfft provided hipfft.h in /opt/rocm/include.
# Workaround: Only use hipfft include directory with hipfft target and place before other hip targets in lib list
if(HIPFFT_INCLUDE_DIRS)
set_property(TARGET hip::hipfft PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${HIPFFT_INCLUDE_DIRS})
endif()
list(APPEND SPFFT_EXTERNAL_LIBS hip::hipfft)
endif()
list(APPEND SPFFT_EXTERNAL_LIBS hip::host roc::rocfft)
# Previously used option for flags.
if(HIP_HCC_FLAGS)
message(WARNING "HIP_HCC_FLAGS has no effect. Use CMAKE_HIP_FLAGS for flags and CMAKE_HIP_ARCHITECTURES for arch instead.")
endif()
endif()
if(SPFFT_MPI)
find_package(MPI COMPONENTS CXX REQUIRED)
list(APPEND SPFFT_EXTERNAL_LIBS MPI::MPI_CXX)
endif()
if(SPFFT_OMP)
find_package(OpenMP COMPONENTS CXX REQUIRED)
list(APPEND SPFFT_EXTERNAL_LIBS OpenMP::OpenMP_CXX)
endif()
if(SPFFT_GPU_DIRECT)
message(STATUS "GPU Direct support enabled: Additional environment variables might have to be set before execution. (e.g \"export MPICH_RDMA_ENABLED_CUDA=1\")")
endif()
# FFTW library must be found if not set to AUTO
set(_SPFFT_FIND_FFTW_LIB_OPTION)
if(NOT ${SPFFT_FFTW_LIB} STREQUAL "AUTO")
set(_SPFFT_FIND_FFTW_LIB_OPTION REQUIRED)
endif()
set(SPFFT_MKL OFF)
set(SPFFT_ARMPL OFF)
set(SPFFT_FFTW OFF)
# Look for MKL first
if(${SPFFT_FFTW_LIB} STREQUAL "AUTO" OR ${SPFFT_FFTW_LIB} STREQUAL "MKL")
# Use MKL if available, otherwise require FFTW3
if(UNIX AND NOT APPLE)
# prefer static MKL in Linux. Together with "-Wl,--exclude-libs,ALL",
# symbols are not visible for linking afterwards and no conflicts with other MKL versions of other libraries should exist.
set(_TMP_SAVE ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .so)
endif()
find_package(MKLSequential ${_SPFFT_FIND_FFTW_LIB_OPTION})
if(UNIX AND NOT APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_TMP_SAVE})
unset(_TMP_SAVE)
endif()
if(TARGET MKL::Sequential)
list(APPEND SPFFT_EXTERNAL_LIBS MKL::Sequential)
list(APPEND SPFFT_EXTERNAL_PKG_PACKAGES mkl-dynamic-lp64-seq)
set(SPFFT_MKL ON)
endif()
endif()
# Look for ARM PL
if(NOT SPFFT_MKL AND ${SPFFT_FFTW_LIB} STREQUAL "AUTO" OR ${SPFFT_FFTW_LIB} STREQUAL "ARMPL")
find_package(ARMPL ${_SPFFT_FIND_FFTW_LIB_OPTION})
if(TARGET ARM::pl)
list(APPEND SPFFT_EXTERNAL_LIBS ARM::pl)
set(SPFFT_ARMPL ON)
endif()
endif()
# Look for FFTW library if required
if(NOT SPFFT_MKL AND NOT SPFFT_ARMPL)
find_package(FFTW REQUIRED)
list(APPEND SPFFT_EXTERNAL_LIBS FFTW::FFTW)
if(SPFFT_SINGLE_PRECISION)
find_package(FFTWF REQUIRED)
list(APPEND SPFFT_EXTERNAL_LIBS FFTWF::FFTWF)
endif()
list(APPEND SPFFT_EXTERNAL_PKG_PACKAGES fftw3)
set(SPFFT_FFTW ON)
endif()
# generate config.h
configure_file(include/spfft/config.h.in ${PROJECT_BINARY_DIR}/spfft/config.h)
list(APPEND SPFFT_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src)
list(APPEND SPFFT_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include)
list(APPEND SPFFT_INCLUDE_DIRS ${PROJECT_BINARY_DIR})
list(APPEND SPFFT_EXTERNAL_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/ext)
#############################################################################
# All include dirs and definitions must be set before sub-directory is added!
#############################################################################
add_subdirectory(src)
# add tests for developement
if(SPFFT_BUILD_TESTS)
add_subdirectory(tests)
endif()
# reset cmake library suffixes
if(SPFFT_STATIC)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVE})
endif()
|