-
Notifications
You must be signed in to change notification settings - Fork 72
/
CMakeLists.txt
284 lines (245 loc) · 12 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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
cmake_minimum_required(VERSION 3.19)
project(finufft VERSION 2.2.0 LANGUAGES C CXX)
set(GNU_LIKE_FRONTENDS AppleClang Clang GNU)
if (CMAKE_CXX_COMPILER_ID IN_LIST GNU_LIKE_FRONTENDS)
# Set custom compiler flags for gcc-compatible compilers
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -funroll-loops")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG -funroll-loops")
endif ()
include(CTest)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "ppc|ppc64|powerpc|powerpc64" OR (APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc|ppc64"))
# PowerPC arch does not have -march flag.
set(FINUFFT_ARCH_FLAGS "-mtune=native" CACHE STRING "Compiler flags for specifying target architecture.")
else ()
set(FINUFFT_ARCH_FLAGS "-march=native" CACHE STRING "Compiler flags for specifying target architecture.")
endif ()
set(FINUFFT_FFTW_SUFFIX "OpenMP" CACHE STRING "Suffix for FFTW libraries (e.g. OpenMP, Threads etc.)")
set(FINUFFT_FFTW_LIBRARIES "DEFAULT" CACHE STRING "Specify a custom FFTW library")
# All options go here
# sphinx tag (don't remove): @cmake_opts_start
option(FINUFFT_BUILD_EXAMPLES "Whether to build the FINUFFT examples" OFF)
option(FINUFFT_BUILD_TESTS "Whether to build the FINUFFT tests" OFF)
option(FINUFFT_BUILD_FORTRAN "Whether to build the FINUFFT Fortran examples" OFF)
option(FINUFFT_BUILD_MATLAB "Whether to build the FINUFFT Matlab interface" OFF)
option(FINUFFT_ENABLE_SANITIZERS "Whether to enable sanitizers, only effective for Debug configuration." ON)
option(FINUFFT_USE_OPENMP "Whether to use OpenMP for parallelization. If disabled, the finufft library will be single threaded. This does not affect the choice of FFTW library." ON)
option(FINUFFT_USE_CUDA "Whether to build CUDA accelerated FINUFFT library (libcufinufft). This is completely independent of the main FINUFFT library" OFF)
option(FINUFFT_USE_CPU "Whether to build the ordinary FINUFFT library (libfinufft)." ON)
option(FINUFFT_STATIC_LINKING "Whether to link the static FINUFFT library (libfinufft_static)." ON)
option(FINUFFT_BUILD_DEVEL "Whether to build developement executables" OFF)
# sphinx tag (don't remove): @cmake_opts_end
if (FINUFFT_USE_CPU)
# suppress Windows warnings about "unsafe" functions
if (WIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif ()
# make apple with gnu use old linker, new linker breaks, see issue #360
if ((APPLE) AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
add_link_options("-ld64")
endif ()
set(CPM_DOWNLOAD_VERSION 0.38.0)
set(FFTW_VERSION 3.3.10)
include(cmake/setupCPM.cmake)
include(cmake/setupFFTW.cmake)
endif ()
if (FINUFFT_BUILD_MATLAB)
# When building for matlab, we will fetch the OpenMP library used by matlab
# instead of system default for compatibility.
find_package(Matlab REQUIRED)
find_library(matlab_iomp5_lib NAMES iomp5 HINTS ${Matlab_ROOT_DIR}/sys/os/ PATH_SUFFIXES glnxa64 maci64)
find_library(pthreads_lib NAMES pthread CMAKE_FIND_ROOT_PATH_BOTH)
# Create a "fake" imported library pointing to the matlab openmp implementation
add_library(OpenMP::OpenMP_CXX SHARED IMPORTED)
set_target_properties(OpenMP::OpenMP_CXX PROPERTIES IMPORTED_LOCATION ${matlab_iomp5_lib})
target_link_libraries(OpenMP::OpenMP_CXX INTERFACE ${pthreads_lib})
# Set the OpenMP flag.
if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
target_compile_options(OpenMP::OpenMP_CXX INTERFACE -Xclang -fopenmp)
else ()
target_compile_options(OpenMP::OpenMP_CXX INTERFACE -fopenmp)
endif ()
else ()
# For non-matlab builds, find system OpenMP
if (FINUFFT_USE_OPENMP)
find_package(OpenMP REQUIRED)
endif ()
endif ()
# This set of sources is compiled twice, once in single precision and once in double precision
# The single precision compilation is done with -DSINGLE
set(FINUFFT_PRECISION_DEPENDENT_SOURCES src/finufft.cpp src/simpleinterfaces.cpp src/spreadinterp.cpp src/utils.cpp fortran/finufftfort.cpp)
# Set of compilers which behave like gcc
set(FINUFFT_GNU_LIKE_COMPILERS AppleClang Clang GNU)
# Utility function to enable ASAN on debug builds
function(enable_asan target)
if (NOT FINUFFT_ENABLE_SANITIZERS)
return()
endif ()
if (CMAKE_CXX_COMPILER_ID IN_LIST FINUFFT_GNU_LIKE_COMPILERS)
# Enable only on clang / gcc compilers.
target_compile_options(${target} PRIVATE $<$<CONFIG:DEBUG>:-fsanitize=address>)
target_link_options(${target} PRIVATE $<$<CONFIG:DEBUG>:-fsanitize=address>)
endif ()
endfunction()
# Utility function to link static/dynamic lib
function(finufft_link_test target)
if (FINUFFT_STATIC_LINKING)
target_link_libraries(${target} PRIVATE finufft_static)
if (FINUFFT_USE_OPENMP)
target_link_libraries(${target} PRIVATE OpenMP::OpenMP_CXX)
if (WIN32)
target_link_options(${target} PRIVATE ${OpenMP_CXX_FLAGS})
endif ()
endif ()
else ()
target_link_libraries(${target} PRIVATE finufft)
if (WIN32)
target_compile_definitions(${target} PRIVATE FINUFFT_DLL)
endif ()
endif ()
enable_asan(${target})
endfunction()
# Utility function to set finufft compilation options.
function(set_finufft_options target)
set_property(TARGET ${target} PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET ${target} PROPERTY CMAKE_CXX_STANDARD 14)
enable_asan(${target})
target_compile_options(${target} PRIVATE SHELL:$<$<CONFIG:Release,RelWithDebInfo>:${FINUFFT_ARCH_FLAGS}>)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Enable cx-limited-range on supported compilers
target_compile_options(${target} PRIVATE $<$<CONFIG:Release,RelWithDebInfo>:-fcx-limited-range>)
endif ()
target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_include_directories(${target} SYSTEM INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
if (FINUFFT_USE_OPENMP)
target_link_libraries(${target} PRIVATE OpenMP::OpenMP_CXX)
# there are issues on windows with OpenMP and CMake, so we need to manually add the flags
# otherwise there are link errors
if (WIN32)
target_link_options(${target} PRIVATE ${OpenMP_CXX_FLAGS})
endif ()
else ()
if (CMAKE_CXX_COMPILER_ID IN_LIST FINUFFT_GNU_LIKE_COMPILERS)
# OpenMP disabled, suppress unknown pragma warnings to avoid spam.
target_compile_options(${target} PRIVATE "-Wno-unknown-pragmas")
endif ()
endif ()
# FFTW CMAKE file includes the APIs only as an install target, so we need to manually
# include them since we need them for build not for install
# trying to include them directly into the fftw and fftwf targets causes issues with
# the latest version of cmake, so we do it here instead.
if ((NOT FFTW_FOUND) OR (FINUFFT_FFTW_LIBRARIES STREQUAL DOWNLOAD))
list(GET FINUFFT_FFTW_LIBRARIES 0 element)
get_property(FFTW_SOURCE_DIR TARGET ${element} PROPERTY SOURCE_DIR)
set(FFTW_INCLUDE_DIR ${FFTW_SOURCE_DIR}/api)
target_include_directories(${target} PUBLIC ${FFTW_INCLUDE_DIR})
endif ()
endfunction()
if (FINUFFT_USE_CPU)
# Main finufft libraries
add_library(finufft_f32 OBJECT ${FINUFFT_PRECISION_DEPENDENT_SOURCES})
target_compile_definitions(finufft_f32 PRIVATE SINGLE)
set_finufft_options(finufft_f32)
target_link_libraries(finufft_f32 PUBLIC ${FINUFFT_FFTW_LIBRARIES})
add_library(finufft_f64 OBJECT ${FINUFFT_PRECISION_DEPENDENT_SOURCES})
target_compile_definitions(finufft_f64 PRIVATE)
set_finufft_options(finufft_f64)
target_link_libraries(finufft_f64 PUBLIC ${FINUFFT_FFTW_LIBRARIES})
if (WIN32)
add_library(finufft_f32_dll OBJECT ${FINUFFT_PRECISION_DEPENDENT_SOURCES})
target_compile_definitions(finufft_f32_dll PRIVATE SINGLE dll_EXPORTS FINUFFT_DLL)
set_finufft_options(finufft_f32_dll)
target_link_libraries(finufft_f32_dll PUBLIC ${FINUFFT_FFTW_LIBRARIES})
add_library(finufft_f64_dll OBJECT ${FINUFFT_PRECISION_DEPENDENT_SOURCES})
target_compile_definitions(finufft_f64_dll PRIVATE dll_EXPORTS FINUFFT_DLL)
set_finufft_options(finufft_f64_dll)
target_link_libraries(finufft_f64_dll PUBLIC ${FINUFFT_FFTW_LIBRARIES})
endif ()
add_library(finufft SHARED src/utils_precindep.cpp contrib/legendre_rule_fast.cpp)
target_compile_definitions(finufft PRIVATE dll_EXPORTS FINUFFT_DLL)
set_finufft_options(finufft)
if (NOT WIN32)
target_link_libraries(finufft PUBLIC finufft_f32 finufft_f64)
else ()
target_link_libraries(finufft PUBLIC finufft_f32_dll finufft_f64_dll)
endif ()
# windows does not have a math library, so we need to exclude it
if (NOT WIN32)
target_link_libraries(finufft PUBLIC m)
endif ()
target_include_directories(finufft PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_include_directories(finufft SYSTEM INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
add_library(finufft_static STATIC src/utils_precindep.cpp contrib/legendre_rule_fast.cpp)
set_finufft_options(finufft_static)
target_link_libraries(finufft_static PUBLIC finufft_f32 finufft_f64)
# windows does not have a math library, so we need to exclude it
if (NOT WIN32)
target_link_libraries(finufft_static PUBLIC m)
endif ()
target_include_directories(finufft_static PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_include_directories(finufft_static SYSTEM INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
file(GLOB FINUFFT_PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/finufft*.h")
set_target_properties(finufft PROPERTIES PUBLIC_HEADER "${FINUFFT_PUBLIC_HEADERS}")
list(APPEND INSTALL_TARGETS finufft finufft_static)
endif ()
if (FINUFFT_USE_CUDA)
if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
message("FINUFFT WARNING: No CUDA architecture supplied via '-DCMAKE_CUDA_ARCHITECTURES=...', defaulting to '60;70;75;'")
message("See: https://developer.nvidia.com/cuda-gpus for more details on what architecture to supply.")
set(CMAKE_CUDA_ARCHITECTURES "60;70;75" CACHE STRING "" FORCE)
endif ()
enable_language(CUDA)
find_package(CUDAToolkit REQUIRED)
add_subdirectory(src/cuda)
if (BUILD_TESTING AND FINUFFT_BUILD_TESTS)
add_subdirectory(perftest/cuda)
endif ()
list(APPEND INSTALL_TARGETS cufinufft cufinufft_static)
endif ()
# Add tests defined in their own directory
if (BUILD_TESTING AND FINUFFT_BUILD_TESTS AND FINUFFT_USE_CPU)
add_subdirectory(test)
add_subdirectory(perftest)
endif ()
if (BUILD_TESTING AND FINUFFT_BUILD_TESTS AND FINUFFT_USE_CUDA)
add_subdirectory(test/cuda)
endif ()
if (FINUFFT_BUILD_EXAMPLES)
add_subdirectory(examples)
endif ()
if (FINUFFT_BUILD_FORTRAN)
enable_language(Fortran)
add_subdirectory(fortran)
endif ()
if (FINUFFT_BUILD_MATLAB)
add_subdirectory(matlab)
endif ()
if (FINUFFT_BUILD_DEVEL)
add_subdirectory(devel)
endif ()
include(GNUInstallDirs)
install(TARGETS ${INSTALL_TARGETS} PUBLIC_HEADER)
install(FILES ${PROJECT_SOURCE_DIR}/LICENSE
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/licenses/finufft)
if (FINUFFT_USE_CPU)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/examples
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/finufft
PATTERN "CMakeLists.txt" EXCLUDE
PATTERN "README" EXCLUDE
PATTERN "examples/cuda" EXCLUDE
)
if (FINUFFT_BUILD_FORTRAN)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/fortran/examples
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/finufft/fortran
)
install(FILES ${PROJECT_SOURCE_DIR}/include/finufft.fh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
endif ()
endif ()
if (FINUFFT_USE_CUDA)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/examples/cuda
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/finufft/examples
PATTERN "README" EXCLUDE
PATTERN "CMakeLists.txt" EXCLUDE
)
endif ()