COMP: Fix FFTWF-only build on release-5.4#6326
Conversation
|
| Filename | Overview |
|---|---|
| CMake/itkExternal_FFTW.cmake | Fixes the root CMake bug: FFTW3_INCLUDE_DIRS (double-precision) was incorrectly set for FFTW_INCLUDE inside the ITK_USE_FFTWF block; corrected to FFTW3f_INCLUDE_DIRS. |
| Modules/Filtering/FFT/include/itkFFTImageFilterFactory.h | Adds FFTImageFilterEnableFloat/Double predicates (defaulting to true_type) and guards each registration block with if constexpr, preventing instantiation of undefined FFTW proxies when a precision is absent. |
| Modules/Filtering/FFT/include/itkFFTWComplexToComplexFFTImageFilter.h | Adds FFTImageFilterEnableFloat/Double specializations to false_type guarded by preprocessor, and a direct fftw3.h include. Has one spurious extra blank line before namespace close. |
| Modules/Registration/PDEDeformable/include/itkCurvatureRegistrationFilter.h | Correctly restricts the filter guard to ITK_USE_FFTWD only; removes the dead branch that declared RealTypeDFT=double while linking against the float library. |
| pyproject.toml | Temporary WIP commit hardcoding FFTWF-only flags into the default configure task. PR author explicitly marks this as a drop-before-merge commit; merging as-is would permanently change the default Pixi build to single-precision-only. |
| Modules/Filtering/FFT/include/itkFFTWForwardFFTImageFilter.h | Adds per-precision enable specializations and direct fftw3.h include, consistent with the pattern applied across all FFTW filter headers. |
| Modules/Filtering/FFT/test/itkFFT1DImageFilterTest.cxx | Falls back from double to float pixel type when ITK_USE_FFTWD is not defined, allowing the test to run under FFTWF-only builds. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[FFTImageFilterFactory constructor] --> B{FFTImageFilterEnableFloat::value?}
B -->|true constexpr| C[Register float precision]
B -->|false constexpr| D[Skip — no instantiation]
A --> E{FFTImageFilterEnableDouble::value?}
E -->|true constexpr| F[Register double precision]
E -->|false constexpr| G[Skip — no instantiation]
H[FFTW filter header] --> I{ITK_USE_FFTWF defined?}
I -->|NO| J[EnableFloat specializes to false_type]
I -->|YES| K[Inherits true_type default]
H --> L{ITK_USE_FFTWD defined?}
L -->|NO| M[EnableDouble specializes to false_type]
L -->|YES| N[Inherits true_type default]
Reviews (2): Last reviewed commit: "COMP: Restrict CurvatureRegistrationFilt..." | Re-trigger Greptile
|
Companion CI-validation PR #6330 (WIP, targets |
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. |
17509f0 to
231af23
Compare
faf8e60 to
f070dd9
Compare
a37dc47 to
5ee425b
Compare
|
Dropped the WIP CI-forcing commit ( |
|
/azp run |
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.
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.
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.
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.
itkCurvatureRegistrationFilter uses FFTW real-to-real (DCT) transforms implemented only for double precision, so it requires ITK_USE_FFTWD. The prior guard also admitted ITK_USE_FFTWF-only builds, whose single-precision branch emitted a #warning that MSVC rejects as fatal error C1021, breaking the single-precision-only Windows build.
5ee425b to
2477dcc
Compare
|
/azp run ITK.macOS.Python |
Fixes the FFTWF-only (single-precision FFTW) build on
release-5.4. 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.