1cmake_minimum_required(VERSION 2.8) 2project(PRETTY_FAST_FFT) 3 4# smaller library size? 5option(USE_TYPE_FLOAT "activate single precision 'float'?" ON) 6option(USE_TYPE_DOUBLE "activate 'double' precision float?" ON) 7 8# architecture/optimization options 9option(USE_SIMD "use SIMD (SSE/AVX/NEON/ALTIVEC) CPU features? - " ON) 10option(DISABLE_SIMD_AVX "disable AVX CPU features? - " OFF) 11option(USE_SIMD_NEON "force using NEON on ARM? (requires USE_SIMD)" OFF) 12option(USE_SCALAR_VECT "use 4-element vector scalar operations (if no other SIMD)" ON) 13 14# test options 15option(USE_BENCH_FFTW "use (system-installed) FFTW3 in fft benchmark?" OFF) 16option(USE_BENCH_GREEN "use Green FFT in fft benchmark? - if exists in subdir" ON) 17option(USE_BENCH_KISS "use KissFFT in fft benchmark? - if exists in subdir" ON) 18option(USE_BENCH_POCKET "use PocketFFT in fft benchmark? - if exists in subdir" ON) 19 20option(USE_DEBUG_ASAN "use GCC's address sanitizer?" OFF) 21 22option(DISABLE_LINK_WITH_M "Disables linking with m library to build with clangCL from MSVC" OFF) 23 24# C90 requires the gcc extensions for function attributes like always_inline 25# C99 provides the function attributes: no gcc extensions required 26set(CMAKE_C_STANDARD 99) 27set(CMAKE_C_EXTENSIONS OFF) 28 29set(CMAKE_CXX_STANDARD 98) 30set(CMAKE_CXX_STANDARD_REQUIRED ON) 31set(CMAKE_CXX_EXTENSIONS OFF) 32 33 34if ( (NOT USE_TYPE_FLOAT) AND (NOT USE_TYPE_DOUBLE) ) 35 message(FATAL_ERROR "activate at least one of USE_TYPE_FLOAT or USE_TYPE_DOUBLE") 36endif() 37 38 39if (USE_DEBUG_ASAN) 40 set(ASANLIB "asan") 41else() 42 set(ASANLIB "") 43endif() 44 45 46if (USE_BENCH_GREEN) 47 if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/greenffts/CMakeLists.txt") 48 message(STATUS "found subdir greenffts") 49 set(PATH_GREEN "${CMAKE_CURRENT_LIST_DIR}/greenffts") 50 add_subdirectory( "${PATH_GREEN}" ) 51 else() 52 message(WARNING "GreenFFT not found in subdir greenffts") 53 endif() 54endif() 55 56if (USE_BENCH_KISS) 57 # git submodule add https://github.com/hayguen/kissfft.git 58 if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/kissfft/CMakeLists.txt") 59 message(STATUS "found subdir kissfft") 60 set(PATH_KISS "${CMAKE_CURRENT_LIST_DIR}/kissfft") 61 add_subdirectory( "${PATH_KISS}" ) 62 else() 63 message(WARNING "KissFFT not found in subdir kissfft") 64 endif() 65endif() 66 67if (USE_BENCH_POCKET) 68 # git submodule add https://github.com/hayguen/pocketfft.git 69 if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/pocketfft/pocketfft_double.c") 70 message(STATUS "found subdir pocketfft") 71 set(PATH_POCKET "${CMAKE_CURRENT_LIST_DIR}/pocketfft") 72 add_subdirectory( "${PATH_POCKET}" ) 73 else() 74 message(WARNING "PocketFFT not found in subdir pocketfft") 75 endif() 76endif() 77 78 79######################################################################## 80# select the release build type by default to get optimization flags 81######################################################################## 82if(NOT CMAKE_BUILD_TYPE) 83 set(CMAKE_BUILD_TYPE "Release") 84 message(STATUS "Build type not specified: defaulting to release.") 85endif(NOT CMAKE_BUILD_TYPE) 86 87if ( CMAKE_C_COMPILER_ID MATCHES "MSVC" ) 88 # using Visual Studio C++ 89 message(STATUS "INFO: detected MSVC: will not link math lib m") 90 set(MATHLIB "") 91 92 add_definitions("/D_CRT_SECURE_NO_WARNINGS") 93 94 set(MSVC_DISABLED_WARNINGS_LIST 95 "C4996" 96 ) 97 98else() 99 if(DISABLE_LINK_WITH_M) 100 else() 101 message(STATUS "INFO: detected NO MSVC: ${CMAKE_C_COMPILER_ID}: will link math lib m") 102 set(MATHLIB "m") 103 endif() 104endif() 105 106set( SIMD_FLOAT_HDRS simd/pf_float.h simd/pf_sse1_float.h simd/pf_altivec_float.h simd/pf_neon_float.h simd/pf_scalar_float.h ) 107set( SIMD_DOUBLE_HDRS simd/pf_double.h simd/pf_avx_double.h simd/pf_scalar_double.h ) 108 109if (USE_TYPE_FLOAT) 110 set( FLOAT_SOURCES pffft.c pffft.h ${SIMD_FLOAT_HDRS} ) 111else() 112 set( FLOAT_SOURCES ) 113endif() 114 115 116if (USE_TYPE_DOUBLE) 117 set( DOUBLE_SOURCES pffft_double.c pffft_double.h ${SIMD_DOUBLE_HDRS} ) 118else() 119 set( DOUBLE_SOURCES ) 120endif() 121 122###################################################### 123 124add_library(PFFFT STATIC ${FLOAT_SOURCES} ${DOUBLE_SOURCES} pffft_common.c pffft_priv_impl.h pffft.hpp ) 125target_compile_definitions(PFFFT PRIVATE _USE_MATH_DEFINES) 126if (USE_SCALAR_VECT) 127 target_compile_definitions(PFFFT PRIVATE PFFFT_SCALVEC_ENABLED=1) 128endif() 129if (USE_DEBUG_ASAN) 130 target_compile_options(PFFFT PRIVATE "-fsanitize=address") 131endif() 132if (NOT USE_SIMD) 133 target_compile_definitions(PFFFT PRIVATE PFFFT_SIMD_DISABLE=1) 134endif() 135if (USE_SIMD AND USE_SIMD_NEON) 136 target_compile_definitions(PFFFT PRIVATE PFFFT_ENABLE_NEON=1) 137 target_compile_options(PFFFT PRIVATE "-mfpu=neon") 138endif() 139if (USE_SIMD AND USE_TYPE_DOUBLE) 140 if(WIN32) 141 if(DISABLE_SIMD_AVX) 142 set_property(SOURCE pffft_double.c PROPERTY COMPILE_FLAGS "/arch:SSE2") 143 else() 144 set_property(SOURCE pffft_double.c PROPERTY COMPILE_FLAGS "/arch:AVX") 145 endif() 146 else() 147 set_property(SOURCE pffft_double.c PROPERTY COMPILE_FLAGS "-march=native") 148 endif() 149 if(DISABLE_SIMD_AVX) 150 target_compile_definitions(PFFFT PRIVATE PFFFT_AVX_DISABLE=1) 151 endif() 152endif() 153target_link_libraries( PFFFT ${MATHLIB} ) 154set_property(TARGET PFFFT APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES 155 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> 156) 157 158###################################################### 159 160if (USE_TYPE_FLOAT) 161 162 add_library(PFDSP STATIC pf_mixer.cpp pf_mixer.h pf_carrier.cpp pf_carrier.h pf_cic.cpp pf_cic.h fmv.h ) 163 target_compile_definitions(PFDSP PRIVATE _USE_MATH_DEFINES) 164 if (USE_DEBUG_ASAN) 165 target_compile_options(PFDSP PRIVATE "-fsanitize=address") 166 endif() 167 if (USE_SIMD AND USE_SIMD_NEON) 168 target_compile_definitions(PFDSP PRIVATE PFFFT_ENABLE_NEON=1) 169 target_compile_options(PFDSP PRIVATE "-march=armv7-a" "-mfpu=neon") 170 endif() 171 target_link_libraries( PFDSP ${MATHLIB} ) 172 set_property(TARGET PFDSP APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES 173 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> 174 ) 175endif() 176 177###################################################### 178 179add_library(FFTPACK STATIC fftpack.c fftpack.h) 180target_compile_definitions(FFTPACK PRIVATE _USE_MATH_DEFINES) 181target_link_libraries( FFTPACK ${MATHLIB} ) 182set_property(TARGET FFTPACK APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES 183 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> 184) 185 186###################################################### 187 188if (USE_TYPE_FLOAT) 189 # only 'float' supported in PFFASTCONV 190 add_library(PFFASTCONV STATIC pffastconv.c pffastconv.h pffft.h ) 191 target_compile_definitions(PFFASTCONV PRIVATE _USE_MATH_DEFINES) 192 if (USE_DEBUG_ASAN) 193 target_compile_options(PFFASTCONV PRIVATE "-fsanitize=address") 194 endif() 195 target_link_libraries( PFFASTCONV PFFFT ${ASANLIB} ${MATHLIB} ) 196 set_property(TARGET PFFASTCONV APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES 197 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> 198 ) 199endif() 200 201####################################################### 202 203if (USE_TYPE_FLOAT) 204 add_executable( test_pffft_float test_pffft.c ) 205 target_compile_definitions(test_pffft_float PRIVATE _USE_MATH_DEFINES) 206 target_compile_definitions(test_pffft_float PRIVATE PFFFT_ENABLE_FLOAT) 207 target_link_libraries( test_pffft_float PFFFT ${ASANLIB} ) 208endif() 209 210###################################################### 211 212if (USE_TYPE_DOUBLE) 213 add_executable( test_pffft_double test_pffft.c ) 214 target_compile_definitions(test_pffft_double PRIVATE _USE_MATH_DEFINES) 215 target_compile_definitions(test_pffft_double PRIVATE PFFFT_ENABLE_DOUBLE) 216 target_link_libraries( test_pffft_double PFFFT ${ASANLIB} ) 217endif() 218 219###################################################### 220 221add_executable( test_pffft_cpp test_pffft.cpp ) 222target_compile_definitions(test_pffft_cpp PRIVATE _USE_MATH_DEFINES) 223if (USE_TYPE_FLOAT) 224 target_compile_definitions(test_pffft_cpp PRIVATE PFFFT_ENABLE_FLOAT) 225endif() 226if (USE_TYPE_DOUBLE) 227 target_compile_definitions(test_pffft_cpp PRIVATE PFFFT_ENABLE_DOUBLE) 228endif() 229target_link_libraries( test_pffft_cpp PFFFT ${ASANLIB} ) 230 231###################################################### 232 233add_executable( test_pffft_cpp_11 test_pffft.cpp ) 234target_compile_definitions(test_pffft_cpp_11 PRIVATE _USE_MATH_DEFINES) 235if (USE_TYPE_FLOAT) 236 target_compile_definitions(test_pffft_cpp_11 PRIVATE PFFFT_ENABLE_FLOAT) 237endif() 238if (USE_TYPE_DOUBLE) 239 target_compile_definitions(test_pffft_cpp_11 PRIVATE PFFFT_ENABLE_DOUBLE) 240endif() 241target_link_libraries( test_pffft_cpp_11 PFFFT ${ASANLIB} ) 242 243set_property(TARGET test_pffft_cpp_11 PROPERTY CXX_STANDARD 11) 244set_property(TARGET test_pffft_cpp_11 PROPERTY CXX_STANDARD_REQUIRED ON) 245 246###################################################### 247 248if (USE_TYPE_FLOAT) 249 add_executable(test_pffastconv test_pffastconv.c 250 ${SIMD_FLOAT_HDRS} ${SIMD_DOUBLE_HDRS} 251 ) 252 target_compile_definitions(test_pffastconv PRIVATE _USE_MATH_DEFINES) 253 if (USE_DEBUG_ASAN) 254 target_compile_options(test_pffastconv PRIVATE "-fsanitize=address") 255 endif() 256 if (NOT USE_SIMD) 257 target_compile_definitions(test_pffastconv PRIVATE PFFFT_SIMD_DISABLE=1) 258 endif() 259 if (USE_SIMD AND USE_SIMD_NEON) 260 target_compile_definitions(test_pffastconv PRIVATE PFFFT_ENABLE_NEON=1) 261 target_compile_options(test_pffastconv PRIVATE "-mfpu=neon") 262 endif() 263 target_link_libraries( test_pffastconv PFFASTCONV ${ASANLIB} ${MATHLIB} ) 264endif() 265 266###################################################### 267 268if (USE_TYPE_FLOAT) 269 add_executable(bench_pffft_float bench_pffft.c pffft.h fftpack.h) 270 target_compile_definitions(bench_pffft_float PRIVATE _USE_MATH_DEFINES) 271 target_compile_definitions(bench_pffft_float PRIVATE PFFFT_ENABLE_FLOAT) 272 273 target_link_libraries( bench_pffft_float PFFFT FFTPACK ${ASANLIB} ) 274 275 if (USE_BENCH_FFTW) 276 target_compile_definitions(bench_pffft_float PRIVATE HAVE_FFTW=1) 277 target_link_libraries(bench_pffft_float fftw3f) 278 endif() 279 280 if (PATH_GREEN AND USE_BENCH_GREEN) 281 target_compile_definitions(bench_pffft_float PRIVATE HAVE_GREEN_FFTS=1) 282 target_link_libraries(bench_pffft_float GreenFFT) 283 endif() 284 285 if (PATH_KISS AND USE_BENCH_KISS) 286 target_compile_definitions(bench_pffft_float PRIVATE HAVE_KISS_FFT=1) 287 target_link_libraries(bench_pffft_float KissFFT) 288 endif() 289 290 if (PATH_POCKET AND USE_BENCH_POCKET) 291 target_compile_definitions(bench_pffft_float PRIVATE HAVE_POCKET_FFT=1) 292 target_link_libraries(bench_pffft_float PocketFFT) 293 endif() 294 295endif() 296 297if (USE_TYPE_DOUBLE) 298 add_executable(bench_pffft_double bench_pffft.c pffft.h fftpack.h) 299 target_compile_definitions(bench_pffft_double PRIVATE _USE_MATH_DEFINES) 300 target_compile_definitions(bench_pffft_double PRIVATE PFFFT_ENABLE_DOUBLE) 301 target_link_libraries( bench_pffft_double PFFFT ${ASANLIB} ) 302 303 if (USE_BENCH_FFTW) 304 target_compile_definitions(bench_pffft_double PRIVATE HAVE_FFTW=1) 305 target_link_libraries(bench_pffft_double fftw3) 306 endif() 307 308 if (PATH_POCKET AND USE_BENCH_POCKET) 309 target_compile_definitions(bench_pffft_double PRIVATE HAVE_POCKET_FFT=1) 310 target_link_libraries(bench_pffft_double PocketFFT) 311 endif() 312endif() 313 314###################################################### 315 316if (USE_TYPE_FLOAT) 317 add_executable(bench_pf_mixer_float bench_mixers.c) 318 target_compile_definitions(bench_pf_mixer_float PRIVATE _USE_MATH_DEFINES) 319 target_compile_definitions(bench_pf_mixer_float PRIVATE PFFFT_ENABLE_FLOAT) 320 321 target_link_libraries( bench_pf_mixer_float PFDSP ${ASANLIB} ) 322 323endif() 324 325###################################################### 326 327enable_testing() 328 329if (USE_TYPE_FLOAT) 330 331 add_test(NAME bench_pffft_pow2 332 COMMAND "${CMAKE_CURRENT_BINARY_DIR}/bench_pffft_float" 333 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 334 ) 335 336 add_test(NAME bench_pffft_non2 337 COMMAND "${CMAKE_CURRENT_BINARY_DIR}/bench_pffft_float" "--non-pow2" 338 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 339 ) 340 341 add_test(NAME bench_plots 342 COMMAND bash "-c" "${CMAKE_CURRENT_SOURCE_DIR}/plots.sh" 343 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 344 ) 345 346 add_test(NAME test_pfconv_lens_symetric 347 COMMAND "${CMAKE_CURRENT_BINARY_DIR}/test_pffastconv" "--no-bench" "--quick" "--sym" 348 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 349 ) 350 351 add_test(NAME test_pfconv_lens_non_sym 352 COMMAND "${CMAKE_CURRENT_BINARY_DIR}/test_pffastconv" "--no-bench" "--quick" 353 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 354 ) 355 356 add_test(NAME bench_pfconv_symetric 357 COMMAND "${CMAKE_CURRENT_BINARY_DIR}/test_pffastconv" "--no-len" "--sym" 358 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 359 ) 360 361 add_test(NAME bench_pfconv_non_sym 362 COMMAND "${CMAKE_CURRENT_BINARY_DIR}/test_pffastconv" "--no-len" 363 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 364 ) 365 366endif() 367 368