Skip to content

WIP: Fix FFTWF-only build on release-5.4 (CI-validation commit temporary)#6326

Draft
hjmjohnson wants to merge 5 commits into
release-5.4from
fix-fftwf-only-include-release-5.4
Draft

WIP: Fix FFTWF-only build on release-5.4 (CI-validation commit temporary)#6326
hjmjohnson wants to merge 5 commits into
release-5.4from
fix-fftwf-only-include-release-5.4

Conversation

@hjmjohnson
Copy link
Copy Markdown
Member

@hjmjohnson hjmjohnson commented May 22, 2026

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 on release-5.4. Companion to #6330 (same fixes on main).

The two defects (masked by the default dual-precision build)
  1. CMake/itkExternal_FFTW.cmake set FFTW_INCLUDE from the double-precision FFTW3_INCLUDE_DIRS inside the ITK_USE_FFTWF block, leaving it empty in single-precision-only builds (fftw3.h not found).
  2. The FFTW factory instantiated both precisions. FFTImageFilterFactory<FFTWxxx> now consults per-precision predicates (FFTImageFilterEnableFloat/Double) guarded by if constexpr. Each FFTW filter header specializes the predicate to false_type for the absent precision, so the factory does not instantiate fftw::ComplexToComplexProxy<double> (undefined when ITK_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 — including itkTestDriverIncludeRequiredFactories.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=OFF against release-5.4: staged FFTW built its own fftw3.h, and itkTestDriverIncludeRequiredFactories.cxx compiles and links.

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.
@github-actions github-actions Bot added type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots labels May 22, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 22, 2026

Greptile Summary

Fixes a CMake variable typo in the ITK_USE_FFTWF block where FFTW_INCLUDE was mistakenly assigned from FFTW3_INCLUDE_DIRS (the double-precision variable, only populated in the ITK_USE_FFTWD block) instead of FFTW3f_INCLUDE_DIRS, leaving the staged fftw3.h include path empty in single-precision-only builds.

  • Root cause: FFTW3_INCLUDE_DIRS is set only when ITK_USE_FFTWD=ON; when only ITK_USE_FFTWF=ON, it is unset, so FFTW_INCLUDE evaluated to an empty string and the compiler could not locate fftw3.h.
  • Fix: One-line change to reference FFTW3f_INCLUDE_DIRS, which is always set within the same ITK_USE_FFTWF block, correctly pointing to ${FFTW_STAGED_INSTALL_PREFIX}/include.

Confidence Score: 5/5

Safe to merge — the one-line change corrects a variable reference that was wrong only in single-precision-only builds and has no effect when both precisions are enabled.

The change is a single variable rename inside a well-bounded conditional block. FFTW3f_INCLUDE_DIRS is set on the line immediately above in the same block, so the replacement is always valid. The bug was genuinely masked in dual-precision builds, explaining why it reached main. No other code paths are affected.

No files require special attention.

Important Files Changed

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
Loading

Reviews (1): Last reviewed commit: "BUG: Set FFTW_INCLUDE from FFTW3f_INCLUD..." | Re-trigger Greptile

@github-actions github-actions Bot added the area:Filtering Issues affecting the Filtering module label May 22, 2026
@hjmjohnson hjmjohnson changed the base branch from main to release-5.4 May 22, 2026 17:57
@hjmjohnson
Copy link
Copy Markdown
Member Author

Companion CI-validation PR #6330 (WIP, targets main) exercises the FFTWF-only build path that this fix addresses — it forces ITK_USE_FFTWF=ON / ITK_USE_FFTWD=OFF on the Pixi-Cxx leg, which the default dual-precision matrix never covers.

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.
@hjmjohnson hjmjohnson force-pushed the fix-fftwf-only-include-release-5.4 branch from 6620047 to 17509f0 Compare May 22, 2026 18:52
@hjmjohnson hjmjohnson changed the title BUG: Set FFTW_INCLUDE from FFTW3f_INCLUDE_DIRS in FFTWF-only builds WIP: Fix FFTWF-only build on release-5.4 (CI-validation commit temporary) May 22, 2026
@hjmjohnson hjmjohnson marked this pull request as draft May 22, 2026 18:52
@hjmjohnson
Copy link
Copy Markdown
Member Author

@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.
@hjmjohnson hjmjohnson force-pushed the fix-fftwf-only-include-release-5.4 branch from 17509f0 to 231af23 Compare May 22, 2026 19:23
@github-actions github-actions Bot removed the type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances label May 22, 2026
@hjmjohnson hjmjohnson force-pushed the fix-fftwf-only-include-release-5.4 branch from 231af23 to faf8e60 Compare May 22, 2026 19:31
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.
@hjmjohnson hjmjohnson force-pushed the fix-fftwf-only-include-release-5.4 branch from faf8e60 to f070dd9 Compare May 23, 2026 19:23
@github-actions github-actions Bot added the type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct label May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Filtering Issues affecting the Filtering module type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants