WIP: Fix FFTWF-only build on release-5.4 (CI-validation commit temporary)#6326
WIP: Fix FFTWF-only build on release-5.4 (CI-validation commit temporary)#6326hjmjohnson wants to merge 5 commits into
Conversation
In the ITK_USE_FFTWF block, FFTW_INCLUDE was assigned from FFTW3_INCLUDE_DIRS (the double-precision variable), which is only set inside the ITK_USE_FFTWD block. When ITK is configured with ITK_USE_FFTWF=ON and ITK_USE_FFTWD=OFF, FFTW_INCLUDE is left empty, so the staged fftw3.h include directory is never added and ITKFFT fails to compile with "fatal error: 'fftw3.h' file not found". The defect is masked whenever both precisions are enabled because the FFTWD block reassigns FFTW_INCLUDE afterward. Use the single-precision FFTW3f_INCLUDE_DIRS in the FFTWF block so single-precision-only builds resolve the header.
|
| Filename | Overview |
|---|---|
| CMake/itkExternal_FFTW.cmake | Single variable name fix: FFTW3_INCLUDE_DIRS → FFTW3f_INCLUDE_DIRS in the FFTWF block so FFTW_INCLUDE is populated in single-precision-only builds. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[CMake configure] --> B{ITK_USE_SYSTEM_FFTW?}
B -- YES --> Z[Use system-installed FFTW]
B -- NO --> C{ITK_USE_FFTWF?}
C -- YES --> D[ExternalProject_Add fftwf]
D --> E[set FFTW3f_INCLUDE_DIRS = FFTW_STAGED_INSTALL_PREFIX/include]
E --> F["set FFTW_INCLUDE = FFTW3f_INCLUDE_DIRS ✅ (was: FFTW3_INCLUDE_DIRS ❌)"]
C -- NO --> G{ITK_USE_FFTWD?}
F --> G
G -- YES --> H[ExternalProject_Add fftwd]
H --> I[set FFTW3_INCLUDE_DIRS = FFTW_STAGED_INSTALL_PREFIX/include]
I --> J[set FFTW_INCLUDE = FFTW3_INCLUDE_DIRS]
G -- NO --> K[FFTW_INCLUDE used by ITKFFT targets]
J --> K
Reviews (1): Last reviewed commit: "BUG: Set FFTW_INCLUDE from FFTW3f_INCLUD..." | Re-trigger Greptile
|
Companion CI-validation PR #6330 (WIP, targets |
FFTWFFTImageFilterInitFactory unconditionally registered every FFTW
filter for both float and double via FFTImageFilterFactory, whose
constructor instantiated both precisions. The single-precision-only
1-D FFTW filters (e.g. FFTWForward1DFFTImageFilter) form member type
aliases from fftw::ComplexToComplexProxy<PixelType>, which is defined
only for the configured precision. Building with ITK_USE_FFTWF=ON and
ITK_USE_FFTWD=OFF therefore failed to compile ITKFFT
("no type named 'PlanType' in 'itk::fftw::ComplexToComplexProxy<double>'").
Add FFTImageFilterEnableFloat / FFTImageFilterEnableDouble predicates
(both default true) and guard the factory constructor with if constexpr.
The FFTW InitFactory specializes the predicate to false_type for the
precision whose backend is absent, so only the configured precision is
registered. Vnl and other factories are unaffected because the
predicates default to enabling both precisions.
6620047 to
17509f0
Compare
|
@dzenanz Build a 3rd-party app against this, identified an issue with placement of code in .cxx that needs to be in .h files. Adding more CI testing (temporarily) to investigate the completeness of the solution. |
The FFTW filter headers reference FFTW_FORWARD/FFTW_BACKWARD/FFTW_ESTIMATE and other fftw3.h symbols but obtained them only transitively through itkFFTWCommon.h / itkFFTWCommonExtended.h. Those proxy headers guard the fftw3.h include with `#if defined(ITK_USE_FFTWF) || defined(ITK_USE_FFTWD)` without first including itkConfigure.h. When a proxy header is first included before ITK_USE_FFTW* is defined, the guard is false, fftw3.h is skipped, and the proxy's include guard is set so later inclusions are no-ops, leaving the FFTW symbols undeclared at parse time (observed in ITKFFTHeaderTest1 with GCC for single-precision-only builds). Include fftw3.h directly, guarded, in each consuming header so the symbols are visible regardless of header include order.
17509f0 to
231af23
Compare
231af23 to
faf8e60
Compare
The 1D FFT tests hardcoded double, which fails to compile in an ITK_USE_FFTWF=ON, ITK_USE_FFTWD=OFF build because only ComplexToComplexProxy<float> defines PlanType/ComplexType. Select the pixel type from the configured precision so the FFTW backend instantiates a proxy that exists. Backport of the single-precision FFTW 1D-test pixel-type fix from main (PR #6330). The default-backend (Vnl) check is unchanged on release-5.4.
Set ITK_USE_FFTWF=ON, ITK_USE_FFTWD=OFF, ITK_USE_SYSTEM_FFTW=OFF in the configure task so the Pixi CI leg builds the staged single-precision FFTW and compiles ITK against it, exercising the FFTWF-only code paths fixed by the two preceding commits. Not for merge.
faf8e60 to
f070dd9
Compare
WIP — do not merge yet. Fixes the FFTWF-only (single-precision FFTW) build on
release-5.4, and temporarily carries a CI-only commit (17509f0) forcing the Pixi leg to build single-precision-only so the matrix actually exercises the fix. The WIP commit will be dropped once CI is green. Stacked onrelease-5.4. Companion to #6330 (same fixes onmain).The two defects (masked by the default dual-precision build)
CMake/itkExternal_FFTW.cmakesetFFTW_INCLUDEfrom the double-precisionFFTW3_INCLUDE_DIRSinside theITK_USE_FFTWFblock, leaving it empty in single-precision-only builds (fftw3.hnot found).FFTImageFilterFactory<FFTWxxx>now consults per-precision predicates (FFTImageFilterEnableFloat/Double) guarded byif constexpr. Each FFTW filter header specializes the predicate tofalse_typefor the absent precision, so the factory does not instantiatefftw::ComplexToComplexProxy<double>(undefined whenITK_USE_FFTWD=OFF).The specializations live in each FFTW filter header (next to
FFTImageFilterTraits<FFTWxxx>), not in a.cxx, so every translation unit that instantiates the factory — includingitkTestDriverIncludeRequiredFactories.cxx— sees them. (This is the fix learned from #6330, where the.cxx-only specializations left other TUs broken.)Local verification
Built ITKTestKernel on macOS arm64 with
ITK_USE_FFTWF=ON/ITK_USE_FFTWD=OFF/ITK_USE_SYSTEM_FFTW=OFFagainstrelease-5.4: staged FFTW built its ownfftw3.h, anditkTestDriverIncludeRequiredFactories.cxxcompiles and links.