Skip to content

Commit 56516ee

Browse files
authored
FFTW: Windows, OMP & Floats (#4282)
## Summary This improves the FFTW CMake find logic based on the scripts that I developed for HiPACE++/WarpX/ImpactX to find FFTW on various platforms. It helps to find FFTW on Windows, where it is installed by default with CMake, and it uses more details from PkgConfig files on Linux/macOS, such as forwarding defines, using OpenMP acceleration if available. It also chooses sensible defaults to work around known FFTW build system bugs, linked inline. There are also options added to control the defaults, e.g., in package managers that use a different default (e.g., CMake FFTW install on Linux/macOS). ## Additional background See build issues in BLAST-ImpactX/impactx#760 (comment) On Windows, try searching for `FFTW3(f)Config.cmake` files first, because: - Installed `.pc` files wrongly and unconditionally add `-lm` - FFTW/fftw3#236 On Linux & macOS, the Autotools install tries to emulate a CMake config file, but has a bug: - FFTW/fftw3#235 - Thus, by default rely on `.pc` files because we cannot know which install was choosen (otherwise, there is an option for it named `AMReX_FFTW_SEARCH`). ## Checklist The proposed changes: - [ ] fix a bug or incorrect behavior in AMReX - [x] add new capabilities to AMReX - [ ] changes answers in the test suite to more than roundoff level - [ ] are likely to significantly affect the results of downstream AMReX users - [ ] include documentation in the code and/or rst files, if appropriate
1 parent 3a34576 commit 56516ee

File tree

1 file changed

+119
-22
lines changed

1 file changed

+119
-22
lines changed

Tools/CMake/FindAMReXFFTW.cmake

Lines changed: 119 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,142 @@ Finds the FFTW library.
77
Imported Targets
88
^^^^^^^^^^^^^^^^
99
10-
This module provides the following imported target, if found:
10+
This module provides the following imported target:
1111
12-
``FFTW``
12+
``AMReX::FFTW``
1313
The FFTW library
1414
15+
Options/Control Variables
16+
^^^^^^^^^^^^^^^^^^^^^^^^^
17+
18+
``AMReX_FFTW_SEARCH``
19+
FFTW search method (PKGCONFIG/CMAKE).
20+
Defaults to CMake config packages on Windows and to PkgConfig pc files on Linux/macOS.
21+
22+
``AMReX_FFTW_IGNORE_OMP``
23+
Ignore FFTW3 OpenMP support, even if found.
24+
1525
Result Variables
1626
^^^^^^^^^^^^^^^^
1727
1828
This will define the following variables:
1929
2030
``AMReXFFTW_FOUND``
21-
True if the hypre library has been found.
22-
``FFTW_INCLUDES``
23-
Include directories needed to use FFTW.
24-
``FFTW_LIBRARIES``
25-
Libraries needed to link to FFTW.
31+
True if the FFTW library has been found.
2632
2733
This will also create an imported target, AMReX::FFTW.
34+
2835
#]=======================================================================]
2936

30-
if (NOT FFTW_INCLUDES)
31-
find_path(FFTW_INCLUDES NAMES "fftw3.h" HINTS ${FFTW_ROOT}/include)
32-
endif()
37+
# Helper Functions ############################################################
38+
#
39+
option(AMReX_FFTW_IGNORE_OMP "Ignore FFTW3's OpenMP support, even if found" OFF)
40+
mark_as_advanced(AMReX_FFTW_IGNORE_OMP)
3341

34-
if (NOT FFTW_LIBRARIES)
35-
find_library(FFTW_LIBRARY NAMES "fftw3" HINTS ${FFTW_ROOT}/lib)
36-
find_library(FFTWF_LIBRARY NAMES "fftw3f" HINTS ${FFTW_ROOT}/lib)
37-
set(FFTW_LIBRARIES ${FFTW_LIBRARY} ${FFTWF_LIBRARY})
38-
endif()
42+
# Set the AMReX_FFTW_OMP=1 define on AMReX::FFTW if TRUE and print
43+
# a message
44+
#
45+
function(fftw_add_define HAS_FFTW_OMP_LIB)
46+
if(HAS_FFTW_OMP_LIB)
47+
message(STATUS "FFTW: Found OpenMP support")
48+
target_compile_definitions(AMReX::FFTW INTERFACE AMReX_FFTW_OMP=1)
49+
else()
50+
message(STATUS "FFTW: Could NOT find OpenMP support")
51+
endif()
52+
endfunction()
3953

40-
include(FindPackageHandleStandardArgs)
54+
# Check if the found FFTW install location has an _omp library, e.g.,
55+
# libfftw3(f)_omp.(a|so) shipped and if yes, set the AMReX_FFTW_OMP=1 define.
56+
#
57+
function(fftw_check_omp library_paths fftw_precision_suffix)
58+
find_library(HAS_FFTW_OMP_LIB${fftw_precision_suffix} fftw3${fftw_precision_suffix}_omp
59+
PATHS ${library_paths}
60+
# this is intentional, so we don't mix different FFTW installs
61+
# and only check what is in the location hinted by the
62+
# "library_paths" variable
63+
NO_DEFAULT_PATH
64+
NO_PACKAGE_ROOT_PATH
65+
NO_CMAKE_PATH
66+
NO_CMAKE_ENVIRONMENT_PATH
67+
NO_SYSTEM_ENVIRONMENT_PATH
68+
NO_CMAKE_SYSTEM_PATH
69+
NO_CMAKE_FIND_ROOT_PATH
70+
)
71+
if(HAS_FFTW_OMP_LIB${fftw_precision_suffix})
72+
# the .pc files here forget to link the _omp.a/so files
73+
# explicitly - we add those manually to avoid any trouble,
74+
# e.g., in static builds.
75+
target_link_libraries(AMReX::FFTW INTERFACE ${HAS_FFTW_OMP_LIB${fftw_precision_suffix}})
76+
endif()
4177

42-
find_package_handle_standard_args(AMReXFFTW
43-
REQUIRED_VARS FFTW_LIBRARIES FFTW_INCLUDES)
78+
fftw_add_define("${HAS_FFTW_OMP_LIB${fftw_precision_suffix}}")
79+
endfunction()
80+
81+
82+
# Central FFTW3 Search ###############################################
83+
#
84+
# On Windows, try searching for FFTW3(f)Config.cmake files first
85+
# Installed .pc files wrongly and unconditionally add -lm
86+
# https://github.com/FFTW/fftw3/issues/236
4487

45-
mark_as_advanced(FFTW_LIBRARIES FFTW_INCLUDES)
88+
# On Linux & macOS, note Autotools install bug:
89+
# https://github.com/FFTW/fftw3/issues/235
90+
# Thus, rely on .pc files
91+
92+
set(AMReX_FFTW_SEARCH_VALUES PKGCONFIG CMAKE)
93+
set(AMReX_FFTW_SEARCH_DEFAULT PKGCONFIG)
94+
if(WIN32)
95+
set(AMReX_FFTW_SEARCH_DEFAULT CMAKE)
96+
endif()
97+
set(AMReX_FFTW_SEARCH ${AMReX_FFTW_SEARCH_DEFAULT}
98+
CACHE STRING "FFTW search method (PKGCONFIG/CMAKE)")
99+
set_property(CACHE AMReX_FFTW_SEARCH PROPERTY STRINGS ${AMReX_FFTW_SEARCH_VALUES})
100+
if(NOT AMReX_FFTW_SEARCH IN_LIST AMReX_FFTW_SEARCH_VALUES)
101+
message(FATAL_ERROR "AMReX_FFTW_SEARCH (${AMReX_FFTW_SEARCH}) must be one of ${AMReX_FFTW_SEARCH_VALUES}")
102+
endif()
103+
mark_as_advanced(AMReX_FFTW_SEARCH)
46104

47105
# Create imported target
48106
add_library(AMReX::FFTW INTERFACE IMPORTED GLOBAL)
49-
target_link_libraries(AMReX::FFTW INTERFACE ${FFTW_LIBRARIES})
50-
set_target_properties(AMReX::FFTW PROPERTIES
51-
INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDES}")
107+
108+
function(fftw_find_precision HFFTWp)
109+
if(AMReX_FFTW_SEARCH STREQUAL CMAKE)
110+
find_package(FFTW3${HFFTWp} CONFIG REQUIRED)
111+
set(AMReX_FFTW_LIBRARY_DIRS "${FFTW3${HFFTWp}_LIBRARY_DIRS}")
112+
message(STATUS "Found FFTW: ${FFTW3${HFFTWp}_DIR} (found version \"${FFTW3${HFFTWp}_VERSION}\")")
113+
else()
114+
find_package(PkgConfig REQUIRED QUIET)
115+
pkg_check_modules(fftw3${HFFTWp} REQUIRED IMPORTED_TARGET fftw3${HFFTWp})
116+
message(STATUS "Found FFTW: ${fftw3${HFFTWp}_PREFIX}")
117+
if(fftw3${HFFTWp}_LIBRARY_DIRS)
118+
set(AMReX_FFTW_LIBRARY_DIRS "${fftw3${HFFTWp}_LIBRARY_DIRS}")
119+
else()
120+
set(AMReX_FFTW_LIBRARY_DIRS "${fftw3${HFFTWp}_LIBDIR}")
121+
endif()
122+
endif()
123+
124+
if(AMReX_FFTW_SEARCH STREQUAL CMAKE)
125+
target_link_libraries(AMReX::FFTW INTERFACE FFTW3::fftw3${HFFTWp})
126+
else()
127+
target_link_libraries(AMReX::FFTW INTERFACE PkgConfig::fftw3${HFFTWp})
128+
endif()
129+
130+
if(AMReX_OMP)
131+
if(AMReX_FFTW_IGNORE_OMP)
132+
message(STATUS "FFTW: Requested to IGNORE OpenMP support")
133+
else()
134+
fftw_check_omp("${AMReX_FFTW_LIBRARY_DIRS}" "${HFFTWp}")
135+
endif()
136+
else()
137+
message(STATUS "FFTW: Did NOT search for OpenMP support (AMReX_OMP is not set)")
138+
endif()
139+
endfunction()
140+
141+
# floating point precision suffixes: we request float and double precision
142+
fftw_find_precision("")
143+
fftw_find_precision("f")
144+
145+
# Vars for CMake config
146+
include(FindPackageHandleStandardArgs)
147+
find_package_handle_standard_args(AMReXFFTW
148+
HANDLE_COMPONENTS)

0 commit comments

Comments
 (0)