Repository navigation
BUG: FFTW follow-ups to #6999: oneMKL via MKLConfig, cuFFTW export, scoped FindFFTW, tests - #7020
hjmjohnson wants to merge 7 commits into
Conversation
952855d to
9c06f36
Compare
|
Rebased onto #6999's new head |
|
Would it be easier to just drop MKL specialization in FindFFTW? Can we drop support for the older CMake configuration variables, and just use MKL's exported targets from its package? Moving to the modern CMake targets has simplified much of the code by dropping the redeious and frequently incorrect management of these variables. P.S. Perhaps the variables could be dropped with FFTW too? |
b671b51 to
6de1618
Compare
|
@blowekamp Good idea. It is now in this PR as the last commit, |
[Medium impact] The PR appears safe to merge; no new actionable issue remains.
|
aa4c748 to
92f8755
Compare
|
@greptileai review this draft before I make it official |
92f8755 to
8441147
Compare
|
@greptileai review this draft before I make it official |
|
Windows retest of #7020 at
The 94 includes the two new A downstream project that links only cuFFTW does not build, but the cause is older than this PR. Not tested: Python wrapping, the AI assistanceBuilds, tests, and this summary were prepared with Claude Code and reviewed by me. |
oneMKL 2024 and later install libraries in MKLROOT/lib, so the lib/intel64-only search failed with "libmkl_intel_ilp64.a not found". Search both directories, and default MKLROOT to the oneAPI install paths instead of the retired compilers_and_libraries locations. find_path() searched system directories before MKLROOT, so a system FFTW fftw3.h (e.g. /usr/include from libfftw3-dev) was used with the oneMKL libraries, and a reconfigure then derived MKLROOT as "/". Search only MKLROOT/include/fftw, and drop a cached path outside it. With ITK_USE_SYSTEM_FFTW, a downstream find_package(ITK) re-runs FindFFTW, which lost a custom MKLROOT. Seed the app's cache with ITK's MKLROOT, as is done for the FFTW library paths, unless the app sets MKLROOT. Honor an existing MKLROOT variable and keep it set under CMP0126 OLD. oneMKL is 64-bit only, so the ia32 branch (with its misspelled WIN check) becomes an error. Rename MKL to oneMKL in the option, comments, and build docs.
The removed ExternalProject forced FFTW_BUILD_TYPE=Release. As an add_subdirectory, FFTW inherited the ITK build type, so a Debug ITK compiled FFTW with -g and no optimization. A debuggable FFTW is of no use to ITK and makes every FFT in a Debug build far slower.
The interface-library registration also ran for modules already added when their src directory was processed, listing 93 of 133 modules twice. Append only modules not yet in the list.
The ITKFFTW module had no test of its own. One GoogleTest driver now checks each enabled precision through ITK::ITKFFTWModule: an impulse must transform to a flat spectrum with a threaded plan. The test is skipped for oneMKL and cuFFTW, which provide their own FFTW interface.
With ITK_USE_CUFFTW and ITK_USE_SYSTEM_FFTW, a downstream find_package(ITK) re-runs FindFFTW but received none of the paths ITK found, so a cuFFTW outside the default search paths was not found and the app failed to configure. Seed the app's cache with CUFFTW_INCLUDE_PATH, CUFFT_LIB, and CUFFTW_LIB, as is done for the FFTW and oneMKL paths. Cache entries the app already set are kept.
With a system FFTW, the exported ITKFFTW code runs FindFFTW in the
scope of the app's find_package(ITK), so FFTW_FOUND, FFTW_INCLUDE,
FFTW{D,F}_LIBRARIES, ITK_USE_MKL, and ITK_USE_CUFFTW were set in the
app and could overwrite its own FFTW variables.
Run the search inside a function. Imported targets do not follow
function scope, so the FFTW::Double and FFTW::Float targets that
ITK::ITKFFTWModule links still reach the app, while the variables and
the CMAKE_MODULE_PATH change stay local. No ITK code reads these
variables, and none of 300 downstream repositories checked does either.
8441147 to
19284a9
Compare
FindFFTW listed oneMKL's static libraries, link flags, and include paths by hand, which broke when oneMKL changed its layout. oneMKL 2021.3 and newer install MKLConfig.cmake, whose MKL::MKL target carries the libraries, link group, and MKL_ILP64 define. Link it with the same static, ILP64, sequential configuration, and pass MKL_DIR rather than MKLROOT to projects that find ITK.
19284a9 to
f3fe9fb
Compare
|
@blowekamp: adopted for oneMKL in f3fe9fb. FindFFTW now finds it only through oneMKL change and limits
cuFFTW on Linux (CUDA 13.3, two RTX 6000 Ada GPUs, GCC 13.3, tip f3fe9fb)
AI assistance
|
Follow-ups to #6999, tracked in #7027: oneMKL found through its own
MKLConfig.cmake(MKL::MKL, per @blowekamp's suggestion), cuFFTW and oneMKL paths passed to downstream projects,FindFFTWvariables kept out of those projects, an optimized bundled FFTW in Debug builds that keeps user flags such as sanitizers, and a GoogleTest for theITKFFTWmodule.Seven commits on
main.BUG: Find oneMKL 2024+ layout and export MKLROOT to FFTW consumerslib/layout; consumers losing a customMKLROOT(greptile P1 on #6999); systemfftw3.hshadowing oneMKL'sBUG: Build bundled FFTW with release optimization in all configurations-gand no optimization; only optimization flags are replaced, so-gand sanitizer flags are kept (greptile P2)BUG: Add each module to ITKTargets_MODULES only onceENH: Add a GoogleTest for the ITKFFTW moduleBUG: Export cuFFTW library paths to FFTW consumersENH: Keep FindFFTW variables out of projects that find ITKFFTW_FOUND,FFTW_INCLUDE,FFTW{D,F}_LIBRARIESset in the consumer's scope; adds a migration guide entryENH: Find oneMKL through its MKLConfig.cmake packageMKL_ILP64define, and include search withMKL::MKL(oneMKL 2021.3+); passesMKL_DIRto consumers; migration guide and build docs updatedoneMKL details
MKLROOT/lib;FindFFTWsearched onlylib/intel64and failed withlibmkl_intel_ilp64.a not found. Defaults pointed at the retiredcompilers_and_librariespaths.ITK_USE_SYSTEM_FFTW, the exportedITKFFTWmodule re-runsFindFFTWdownstream but did not carryMKLROOT, so consumers fell back to the hard-coded default. ITK'sMKLROOTnow seeds the app's cache, the same way ENH: Build FFTW as an ITKFFTW third-party module with FetchContent #6999 seeds the FFTW library paths, unless the app setsMKLROOT.find_path()searches system directories beforeMKLROOT, so a system FFTWfftw3.h(/usr/include, fromlibfftw3-dev) was compiled against oneMKL's libraries. On reconfigure,MKLROOTwas then derived from that path as/, and/was exported to consumers. Items 1 and 3 also affectmainbefore ENH: Build FFTW as an ITKFFTW third-party module with FetchContent #6999.WINvariable; oneMKL is 64-bit only, so it is now an error.Why the FindFFTW variables are kept local rather than renamed
With a system FFTW the exported code runs
FindFFTWin the scope of the app'sfind_package(ITK)(module loading uses macros), so every result variable reached the app. No ITK code reads them, and a search of 300 downstream repositories (the 47 projects in the downstream build forest, including RTK, plus 253 Slicer extensions) found no user. Renaming toFFTW_INCLUDE_DIRS/FFTW_LIBRARIESwould collide with apps' own finders: Plastimatch setsFFTW_LIBRARIESbeforefind_package(ITK). The search now runs inside a function, so only theFFTW::Double/FFTW::Floatimported targets reach the app; the input hints (FFTW_INCLUDE_PATH,FFTW{D,F}_BASE_LIB, ...) are unchanged. Discussion: #6999 (comment).Testing (at `b671b51`, before the patch-identical rebase onto main)
macOS arm64 (Apple clang, CMake 3.26), minimal ITK with
Module_ITKFFT:Module_ITKFFTW=ON(newFFTWModuletests pass, double and float); install has onlylibitkfftw3*andfftw3.h; 6 consumers run-O3(no-g); 4 consumers runFindFFTW.cmakerunFFTW_LIBRARIESbeforefind_package(ITK): before this PR 6FindFFTWvariables leak; now none leak, its value is kept,FFTW::Doubleexists, and it builds and runsCould NOT find FFTW; now: consumer findsFFTW::Floatfrom the exported pathsLinux x86_64 (GCC 13.3, CMake 4.2):
MKLROOT, an override, CMP0126 OLD, and the variable check all runlibfftw3-dev), renamed libraries, no threads library-O3; consumers runShared install-tree consumers on Linux need
LD_LIBRARY_PATHbecause ITK sets no install RPATH (same onmain, tracked in #7027).Windows: @dzenanz tested the oneMKL commit with MSVC 2022 (92/92,
MKLROOTfrom the environment as a backslash path) in #6999 (comment). The release-flags commit has not been re-run on Windows Debug yet.Testing of the last two changes (head
8441147)MKLConfig.cmakepath, Linux x86_64 (GCC 13.3, CMake 4.2, oneMKL 2026.1, static, minimal ITK withModule_ITKFFT):-DMKLROOTMKL_DIRfound; 0 warnings; 91/91 FFT tests; install exportsMKL_DIRunless the app setsMKLROOTMKLROOT,MKLROOToverride, CMP0126 OLD, variable check)MKLROOTonly in the environmentMKL_DIRonlyMKL_LINK=dynamicdynamic(3libmklshared libraries),-DMKL_LINK=staticin the app overrides it, an app settingMKLROOTstill getsdynamicBundled FFTW flags, macOS arm64, Debug: with
CMAKE_C_FLAGS_DEBUGset to-g -fsanitize=address, then-g -fno-omit-frame-pointer, FFTW objects keep those flags plus-O3, with no-O0; FFT tests 94/94. (The sanitizer run itself deadlocks inside the pixi clang ASan runtime at startup on this macOS, before any ITK code runs, so the second flag was used to run the tests.) Linux GCC 13.3, Debug with-g -fno-omit-frame-pointer -I"/tmp/dbg hdrs": the quoted path reaches FFTW intact, with-O3and no-O0; 93/93. MSVC flag removal (/Od /RTC1 /Zi /Ob0->/Zi) checked only with acmake -Pscript.AI assistance
Prepared with Claude Code at @hjmjohnson's direction: reproduced the failures, wrote the changes, and ran the tests above on macOS and a Linux host.