Skip to content

Commit 744e8b2

Browse files
authored
Merge pull request #1 from michaelbacci/feature-light-dependencies
Feature light dependencies
2 parents 663cbb5 + 0d36bd7 commit 744e8b2

18 files changed

+1429
-956
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,9 @@
3333
*.exe
3434
*.out
3535
*.app
36+
37+
# cmake
38+
build
39+
40+
# vscode
41+
.vscode

CMakeLists.txt

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ cmake_minimum_required(VERSION 3.1.3) # 3.1.3 for set(CMAKE_CXX_STANDARD 14)
1515
project(xtensor-fftw)
1616

1717
set(XTENSOR_FFTW_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
18-
18+
set(FFTW_INCLUDE_CUSTOM_DIRS "" CACHE STRING "Set the FFTW include dir without the requirement of FFTW installation.")
19+
set(FFTW_LINK_FLAGS "" CACHE STRING "Set the CXX library to link, e.g.: -L/usr/local -lfftw3")
1920
#--------------------------------------- versioning
2021

2122
file(STRINGS "${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/xtensor-fftw_config.hpp" xtensor-fftw_version_defines
@@ -46,6 +47,35 @@ OPTION(FIX_RPATH "Correctly set rpath for the linker" OFF)
4647
OPTION(DEFAULT_COLUMN_MAJOR "Set xtensor default layout to column major. This is currently not supported, since FFTW demands row major layout." OFF)
4748
OPTION(COVERAGE "Enable coverage compile flags (gcc only!)" OFF)
4849
OPTION(DISABLE_EXCEPTIONS "Disable C++ exceptions" OFF)
50+
OPTION(FFTW_USE_FLOAT "Enable FFTW Float type" ON)
51+
OPTION(FFTW_USE_DOUBLE "Enable FFTW Double type" ON)
52+
OPTION(FFTW_USE_LONG_DOUBLE "Enable FFTW Long Double type" ON)
53+
54+
if(FFTW_USE_FLOAT)
55+
add_definitions(-DXTENSOR_FFTW_USE_FLOAT)
56+
set(REQUIRE_FLOAT_LIB "FLOAT_LIB")
57+
else()
58+
set(REQUIRE_FLOAT_LIB "")
59+
endif()
60+
61+
if(FFTW_USE_DOUBLE)
62+
add_definitions(-DXTENSOR_FFTW_USE_DOUBLE)
63+
set(REQUIRE_DOUBLE_LIB "DOUBLE_LIB")
64+
else()
65+
set(REQUIRE_DOUBLE_LIB "")
66+
endif()
67+
68+
if(FFTW_USE_LONG_DOUBLE AND NOT MSVC)
69+
add_definitions(-DXTENSOR_FFTW_USE_LONG_DOUBLE)
70+
set(REQUIRE_LONG_DOUBLE_LIB "LONGDOUBLE_LIB")
71+
else()
72+
set(REQUIRE_LONG_DOUBLE_LIB "")
73+
set(FFTW_USE_LONG_DOUBLE OFF)
74+
endif()
75+
76+
if(NOT REQUIRE_FLOAT_LIB AND NOT REQUIRE_DOUBLE_LIB AND NOT REQUIRE_LONG_DOUBLE_LIB)
77+
message(FATAL_ERROR "Please, select at least one of the available FFTW type libraries")
78+
endif()
4979

5080
if (COVERAGE)
5181
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU")
@@ -65,21 +95,6 @@ set(CMAKE_CXX_EXTENSIONS NO)
6595
# .. our own
6696
include_directories(${XTENSOR_FFTW_INCLUDE_DIR})
6797

68-
# .. xtensor
69-
set(xtensor_REQUIRED_VERSION 0.20.9)
70-
if(TARGET xtensor)
71-
set(xtensor_VERSION ${XTENSOR_VERSION_MAJOR}.${XTENSOR_VERSION_MINOR}.${XTENSOR_VERSION_PATCH})
72-
# Note: This is not SEMVER compatible comparison
73-
if( NOT ${xtensor_VERSION} VERSION_GREATER_EQUAL ${xtensor_REQUIRED_VERSION})
74-
message(ERROR "Mismatch xtensor versions. Found '${xtensor_VERSION}' but requires: '${xtensor_REQUIRED_VERSION}'")
75-
else()
76-
message(STATUS "Found xtensor v${xtensor_VERSION}")
77-
endif()
78-
else()
79-
find_package(xtensor ${xtensor_REQUIRED_VERSION} REQUIRED)
80-
message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor")
81-
endif()
82-
8398
# .. xtl
8499
set(xtl_REQUIRED_VERSION 0.6.9)
85100
if(TARGET xtl)
@@ -95,18 +110,51 @@ else()
95110
message(STATUS "Found xtl: ${xtl_INCLUDE_DIRS}/xtl")
96111
endif()
97112

113+
# .. xtensor
114+
set(xtensor_REQUIRED_VERSION 0.20.9)
115+
if(TARGET xtensor)
116+
set(xtensor_VERSION ${XTENSOR_VERSION_MAJOR}.${XTENSOR_VERSION_MINOR}.${XTENSOR_VERSION_PATCH})
117+
# Note: This is not SEMVER compatible comparison
118+
if( NOT ${xtensor_VERSION} VERSION_GREATER_EQUAL ${xtensor_REQUIRED_VERSION})
119+
message(ERROR "Mismatch xtensor versions. Found '${xtensor_VERSION}' but requires: '${xtensor_REQUIRED_VERSION}'")
120+
else()
121+
message(STATUS "Found xtensor v${xtensor_VERSION}")
122+
endif()
123+
else()
124+
find_package(xtensor ${xtensor_REQUIRED_VERSION} REQUIRED)
125+
message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor")
126+
endif()
127+
98128
# .. fftw
99-
if(MSVC)
100-
# no long double component, since in the Windows conda-forge build it is not available
101-
# and the "official" prebuilt long double library can only be used from MinGW
102-
find_package(FFTW REQUIRED
103-
COMPONENTS FLOAT_LIB DOUBLE_LIB)
104-
add_definitions(-DFFTW_NO_LONGDOUBLE)
129+
if(NOT "${FFTW_INCLUDE_CUSTOM_DIRS}" STREQUAL "")
130+
include_directories(${FFTW_INCLUDE_CUSTOM_DIRS})
105131
else()
106-
find_package(FFTW REQUIRED
107-
COMPONENTS FLOAT_LIB DOUBLE_LIB LONGDOUBLE_LIB)
108-
endif(MSVC)
109-
include_directories(${FFTW_INCLUDE_DIRS})
132+
if(MSVC)
133+
# no long double component, since in the Windows conda-forge build it is not available
134+
# and the "official" prebuilt long double library can only be used from MinGW
135+
find_package(FFTW REQUIRED
136+
COMPONENTS ${REQUIRE_FLOAT_LIB} ${REQUIRE_DOUBLE_LIB})
137+
add_definitions(-DFFTW_NO_LONGDOUBLE)
138+
else(MSVC)
139+
find_package(FFTW REQUIRED
140+
COMPONENTS ${REQUIRE_FLOAT_LIB} ${REQUIRE_DOUBLE_LIB} ${REQUIRE_LONG_DOUBLE_LIB})
141+
endif()
142+
include_directories(${FFTW_INCLUDE_DIRS})
143+
144+
# link only with selected libraries
145+
set(FFTW_LINK_FLAGS "")
146+
if(FFTW_USE_FLOAT)
147+
set(FFTW_LINK_FLAGS ${FFTW_FLOAT_LIB})
148+
endif()
149+
150+
if(FFTW_USE_DOUBLE)
151+
set(FFTW_LINK_FLAGS ${FFTW_LINK_FLAGS} ${FFTW_DOUBLE_LIB})
152+
endif()
153+
154+
if(FFTW_USE_LONG_DOUBLE)
155+
set(FFTW_LINK_FLAGS ${FFTW_LINK_FLAGS} ${FFTW_LONGDOUBLE_LIB})
156+
endif()
157+
endif()
110158

111159
# warnings (gcc and clang)
112160
if (COMPILE_WARNINGS)
@@ -129,7 +177,12 @@ endif(FIX_RPATH)
129177
#--------------------------------------- library contents
130178

131179
set(XTENSOR_FFTW_HEADERS
180+
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/basic_double.hpp
181+
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/basic_float.hpp
182+
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/basic_long_double.hpp
183+
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/basic_option.hpp
132184
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/basic.hpp
185+
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/common.hpp
133186
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/helper.hpp
134187
${XTENSOR_FFTW_INCLUDE_DIR}/xtensor-fftw/xtensor-fftw_config.hpp
135188
)

README.md

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,25 @@ _xtensor-fftw_ is a header-only library.
5858
To use, include one of the header files in the `include` directory, e.g. `xtensor-fftw/basic.hpp`, in your c++ code.
5959
To compile, one should also include the paths to the FFTW header and libraries and link to the appropriate FFTW library.
6060

61+
FFTW allows three modes of calculus : `float`, `double` and `long double`.
62+
The impact of the precision type can be see below in the benchmark results.
63+
Use the following matrix to include, compile and link the right target:
64+
65+
| `#include` | `precision types` | `xtensor-fftw compile options` | `FFTW compile options` |
66+
|------------------------------------|----------------------------|-----------------------------------|-------------------------|
67+
| xtensor-fftw/basic_float.hpp | float | -DXTENSOR_FFTW_USE_FLOAT=ON | -DENABLE_FLOAT=ON |
68+
| xtensor-fftw/basic_double.hpp | double | -DXTENSOR_FFTW_USE_DOUBLE=ON | -DENABLE_DOUBLE=ON |
69+
| xtensor-fftw/basic_long_double.hpp | long double | -DXTENSOR_FFTW_USE_LONG_DOUBLE=ON | -DENABLE_LONGDOUBLE=ON |
70+
| xtensor-fftw/basic_option.hpp | depends by compile options | subset of above options | subset of above options |
71+
| xtensor-fftw/basic.hpp | all types | no option | all above options |
72+
73+
Specify only the required precision type to reduce the dependencies size of your application (for example for a Mobile App it matters), in fact FFTW needs to compile a specific library for each precision thus creating:
74+
* `libfftw3f` for float precision
75+
* `libfftw3` for double precision
76+
* `libfftw3l` for long double precision
77+
78+
>__*Notes*__: FFTW allow SIMD instructions (SSE,SSE2,AVX,AVX2), OpenMP and Threads optimizations. Take a look to the availables options before compile it.
79+
6180
The functions in `xtensor-fftw/basic.hpp` mimic the behavior of `numpy.fft` as much as possible.
6281
In most cases transforms on identical input data should produce identical results within reasonable machine precision error bounds.
6382
However, there are a few differences that one should keep in mind:
@@ -126,11 +145,10 @@ What follows are instructions for compiling and running the _xtensor-fftw_ tests
126145
These also serve as an example of how to do build your own code using _xtensor-fftw_ (excluding the GoogleTest specific parts).
127146
128147
### Dependencies for building tests
148+
129149
The main dependency is a version of FFTW 3.
130-
For the tests, we need the floating point version which is enabled in the FFTW configuration step using:
131-
```bash
132-
./configure --enable-float
133-
```
150+
To enable all the precision types, FFTW must be compiled with the related flags:
151+
`cmake -DENABLE_FLOAT:BOOL=ON -DENABLE_LONGDOUBLE:BOOL=ON /path/of/fftw3-src`
134152
135153
CMake and _xtensor_ must also be installed in order to compile the _xtensor-fftw_ tests.
136154
Both can either be installed through Conda or built/installed manually.
@@ -179,6 +197,64 @@ cd test
179197
./test_xtensor-fftw
180198
```
181199

200+
## Advanced Setting
201+
202+
This section shows how to configure `cmake` in order to exploit advanced settings.
203+
204+
### Use only Double precision
205+
206+
After a standard installation of FFTW library without specify a particular options, this command allow to run Test and Benchmarks using only `double` precision:
207+
208+
```cmake
209+
cmake -DBUILD_BENCHMARK=ON -DDOWNLOAD_GBENCH=ON -DBUILD_TESTS=ON -DDOWNLOAD_GTEST=ON -DFFTW_USE_FLOAT=OFF -DFFTW_USE_LONG_DOUBLE=OFF -DFFTW_USE_DOUBLE=ON -DCMAKE_BUILD_TYPE=Release ..
210+
```
211+
212+
Let's see what `./bench/benchmark_xtensor-fftw` produce:
213+
214+
```
215+
Run on (16 X 2300 MHz CPU s)
216+
-------------------------------------------------------------------------------
217+
Benchmark Time CPU Iterations
218+
-------------------------------------------------------------------------------
219+
rfft1Dxarray_double/TransformAndInvert 66375 ns 66354 ns 10149
220+
rfft1Dxarray_double/TransformAndInvert_nD 70856 ns 70829 ns 10128
221+
rfft2Dxarray_double/TransformAndInvert 61264 ns 61256 ns 11456
222+
rfft2Dxarray_double/TransformAndInvert_nD 62297 ns 62269 ns 10851
223+
```
224+
225+
### Manually specify FFTW headers and link flags
226+
227+
This can be very useful: in this case FFTW is not required to be installed, just compiled.
228+
The following command produce the same results as before:
229+
230+
```cmake
231+
cmake -DBUILD_BENCHMARK=ON -DDOWNLOAD_GBENCH=ON -DBUILD_TESTS=ON -DDOWNLOAD_GTEST=ON -DFFTW_USE_FLOAT=OFF -DFFTW_USE_LONG_DOUBLE=OFF -DFFTW_USE_DOUBLE=ON -DFFTW_INCLUDE_CUSTOM_DIRS=/path/to/fftw3/api -DFFTW_LINK_FLAGS="-L/path/to/fftw3/build -lfftw3" ..
232+
```
233+
234+
### Use Intel MKL
235+
236+
Since 2018 Intel has release a version of his famous MKL (Math Kernel Library) with a C++ and Fortran wrapper of FFTW.
237+
Once MKL (or oneAPI MKL) installed on the system enter the following command with adjusted path to your system:
238+
239+
```cmake
240+
cmake -DBUILD_BENCHMARK=ON -DDOWNLOAD_GBENCH=ON -DBUILD_TESTS=ON -DDOWNLOAD_GTEST=ON -DFFTW_USE_FLOAT=OFF -DFFTW_USE_LONG_DOUBLE=OFF -DFFTW_USE_DOUBLE=ON -DFFTW_INCLUDE_CUSTOM_DIRS=/opt/intel/oneapi/mkl/2021.2.0/include/fftw -DFFTW_LINK_FLAGS="-L/opt/intel/oneapi/mkl/2021.2.0/lib -L/opt/intel/oneapi/compiler/2021.2.0/mac/compiler/lib -lmkl_core -lmkl_intel_thread -lmkl_intel_lp64 -liomp5" -DRUN_HAVE_STD_REGEX=0 -DCMAKE_BUILD_TYPE=Release ..
241+
```
242+
243+
Let's see what `./bench/benchmark_xtensor-fftw` now produce:
244+
245+
```
246+
Run on (16 X 2300 MHz CPU s)
247+
-------------------------------------------------------------------------------
248+
Benchmark Time CPU Iterations
249+
-------------------------------------------------------------------------------
250+
rfft1Dxarray_double/TransformAndInvert 9265 ns 9258 ns 58371
251+
rfft1Dxarray_double/TransformAndInvert_nD 9636 ns 9602 ns 73961
252+
rfft2Dxarray_double/TransformAndInvert 34428 ns 34427 ns 20216
253+
rfft2Dxarray_double/TransformAndInvert_nD 37401 ns 37393 ns 19480
254+
```
255+
256+
>__*Note*__: Before running test or benchmark remember to export the intel library path, e.g. on OS X: `export DYLD_LIBRARY_PATH=/opt/intel/oneapi/mkl/2021.2.0/lib/:/opt/intel/oneapi/compiler/2021.2.0/mac/compiler/lib/`
257+
182258
## License
183259

184260
We use a shared copyright model that enables all contributors to maintain the

bench/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,6 @@ add_executable(${XTENSOR_FFTW_TARGET} ${XTENSOR_FFTW_BENCHMARKS} ${XTENSOR_HEADE
101101
if(DOWNLOAD_GBENCH OR GBENCH_SRC_DIR)
102102
add_dependencies(${XTENSOR_FFTW_TARGET} benchmark)
103103
endif()
104-
target_link_libraries(${XTENSOR_FFTW_TARGET} ${benchmark_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${FFTW_FLOAT_LIB} ${FFTW_DOUBLE_LIB} ${FFTW_LONGDOUBLE_LIB})
104+
target_link_libraries(${XTENSOR_FFTW_TARGET} ${benchmark_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${FFTW_LINK_FLAGS})
105105

106106
add_custom_target(xbench COMMAND benchmark_xtensor-fftw DEPENDS ${XTENSOR_FFTW_TARGET})

0 commit comments

Comments
 (0)