-
Notifications
You must be signed in to change notification settings - Fork 11
/
CMakeLists.txt
241 lines (201 loc) · 7.72 KB
/
CMakeLists.txt
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.0)
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()