Skip to content

ENH: Vendor pocketfft as the ITKPocketFFT third-party module#6532

Merged
hjmjohnson merged 1 commit into
InsightSoftwareConsortium:mainfrom
hjmjohnson:thirdparty-pocketfft-vendor
Jul 1, 2026
Merged

ENH: Vendor pocketfft as the ITKPocketFFT third-party module#6532
hjmjohnson merged 1 commit into
InsightSoftwareConsortium:mainfrom
hjmjohnson:thirdparty-pocketfft-vendor

Conversation

@hjmjohnson

Copy link
Copy Markdown
Member

Move the header-only pocketfft from the FFT module include directory into a
proper Modules/ThirdParty/PocketFFT module, vendored from the
InsightSoftwareConsortium/pocketfft
fork via the standard UpdateFromUpstream.sh mechanism.

This gives pocketfft parity with every other ITK third-party inclusion
even though it is a single header file — so that future upstream pocketfft
updates are maintained the same consistent way as eigen, DCMTK, VNL, etc.
(fork with a welcome branch, for/itk-* overlay, UpdateFromUpstream.sh).

Upstream pocketfft has also already merged the fix for the compiler warnings
reported on the CDash build
https://open.cdash.org/builds/11378398/build
(mreineck/pocketfft#32), so the vendored copy is warning-clean with no
ITK-local patch required.

What changed
  • New Modules/ThirdParty/PocketFFT module (Eigen3 header-only model):
    itk-module.cmake, CMakeLists.txt with an ITK_USE_SYSTEM_POCKETFFT
    switch, and UpdateFromUpstream.sh pinned to
    for/itk-pocketfft-cpp-c90e55b.
  • itk_pocketfft.h is the single entry point: it is the only header that
    includes pocketfft_hdronly.h. ITK-specific configuration lives here (not in
    the vendored copy), applied before the include:
  • The vendored pocketfft_hdronly.h keeps upstream defaults, so the fork stays
    a faithful mirror of upstream cpp (which includes Use nullptr instead of 0 in arr default constructor mreineck/pocketfft#32).
  • ITKFFT now DEPENDS ITKPocketFFT; the FFT filters and the deprecated
    vnl_fft_1d shim include itk_pocketfft.h and use the fully-qualified
    itk::detail::pocketfft:: API.
Validation
  • ITKFFT builds; all 20 PocketFFT tests pass.
  • Install places itk_pocketfft.h and itkpocketfft/{pocketfft_hdronly.h, LICENSE.md} under a single include root; an external consumer including only
    itk_pocketfft.h compiles and links, with POCKETFFT_CACHE_SIZE == 16.
  • Symbol check: zero global ::pocketfft symbols; all in
    itk::detail::pocketfft.
  • UpdateFromUpstream.sh re-import reproduces the vendored header byte-for-byte
    with correct two-parent merge topology.
  • pre-commit run --all-files passes.

@github-actions github-actions Bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Enhancement Improvement of existing methods or implementation area:Filtering Issues affecting the Filtering module area:ThirdParty Issues affecting the ThirdParty module labels Jun 30, 2026
@blowekamp

Copy link
Copy Markdown
Member

Looks correct so far

@hjmjohnson hjmjohnson marked this pull request as ready for review June 30, 2026 13:20
@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR extracts pocketfft_hdronly.h from the ITKFFT module's include directory into a proper Modules/ThirdParty/PocketFFT third-party module, bringing it into parity with Eigen3 and other vendored dependencies. ITK-specific configuration (namespace isolation to itk::detail::pocketfft and cache size) is moved into a generated itk_pocketfft.h wrapper rather than embedded in the vendored copy.

  • New ITKPocketFFT module follows the Eigen3 header-only pattern: CMakeLists.txt with ITK_USE_SYSTEM_POCKETFFT switch, UpdateFromUpstream.sh pinned to for/itk-pocketfft-cpp-c90e55b, and a configure_file-generated entry-point header.
  • All six PocketFFT filter headers and vnl_fft_1d.h updated to #include \"itk_pocketfft.h\" and use the fully-qualified itk::detail::pocketfft:: namespace throughout.

Confidence Score: 4/5

The module restructuring is mechanically correct and follows the established Eigen3 pattern closely. The vendored copy and build wiring look sound; the two items worth a second look before merge are the incomplete LICENSE.md and the undocumented system-pocketfft namespace fragility.

The core refactor — moving pocketfft into ThirdParty, generating the entry-point header, updating all callers — is clean and consistent with existing ITK conventions. The LICENSE.md shipped with the vendored copy omits several copyright holders named in the header it licenses, which is a BSD-3-Clause attribution gap. The system-pocketfft path also silently degrades (compile failure) when another library has already pulled in pocketfft under its default namespace; a short comment would make this failure mode diagnosable.

Modules/ThirdParty/PocketFFT/src/itkpocketfft/LICENSE.md (incomplete copyright attribution) and Modules/ThirdParty/PocketFFT/src/itk_pocketfft.h.in (undocumented namespace-collision risk for ITK_USE_SYSTEM_POCKETFFT)

Important Files Changed

Filename Overview
Modules/ThirdParty/PocketFFT/CMakeLists.txt New top-level module CMakeLists following the Eigen3 pattern; correctly sets up vendored vs system paths, runs configure_file, and exposes ITKPocketFFT_INCLUDE_DIRS. Missing install of vendored files is handled in src/CMakeLists.txt via itk_module_impl() → add_subdirectory(src).
Modules/ThirdParty/PocketFFT/src/itk_pocketfft.h.in Generated entry-point header that sets POCKETFFT_NAMESPACE and POCKETFFT_CACHE_SIZE before the upstream include. Uses #ifndef guards which create a fragility for the system-pocketfft path when another library has already included pocketfft_hdronly.h with its default namespace.
Modules/ThirdParty/PocketFFT/src/itkpocketfft/LICENSE.md LICENSE.md covers only the 2010-2018 Max-Planck-Society copyright but pocketfft_hdronly.h names additional copyright holders (Peter Bell 2019-2020, Matteo Frigo/MIT 2003-2014, Tan Ping Liang/Peter Bell 2024, Cris Luengo 2024). The license file is incomplete relative to the code being distributed.
Modules/ThirdParty/PocketFFT/itk-module.cmake Minimal module declaration with no dependencies; follows standard ITK third-party module pattern. DEPENDS followed immediately by DESCRIPTION is correct CMake argument-parsing idiom for zero dependencies.
Modules/ThirdParty/PocketFFT/UpdateFromUpstream.sh Standard ITK update-third-party script pointing to the ISC fork; exact_tree_match=false is appropriate since only two files are imported from upstream. Tag pinned to for/itk-pocketfft-cpp-c90e55b.
Modules/Filtering/FFT/include/itkPocketFFTCommon.h Updated to use itk_pocketfft.h and itk::detail::pocketfft:: namespace throughout; logic is unchanged.
Modules/Filtering/FFT/itk-module.cmake Adds ITKPocketFFT to ITKFFT's DEPENDS list, correctly modeling the new module dependency.
Modules/ThirdParty/VNL/src/vxl/core/vnl/algo/vnl_fft_1d.h Updated deprecated shim to include itk_pocketfft.h and use itk::detail::pocketfft:: namespace. Comment saying 'Requires ITKFFT module' is still accurate since ITKFFT transitively supplies ITKPocketFFT include dirs.
Modules/ThirdParty/PocketFFT/src/itkpocketfft/pocketfft_hdronly.h Vendored upstream pocketfft header; POCKETFFT_CACHE_SIZE default reverted to 0 (ITK's value is now set in itk_pocketfft.h.in), and arr() default-initializes pointer to nullptr instead of 0. Content otherwise mirrors upstream.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    ITKFFT["ITKFFT module\n(itk-module.cmake)"]
    ITKPocketFFT["ITKPocketFFT module\n(ThirdParty)"]
    itk_pocketfft_h["itk_pocketfft.h\n(generated via configure_file)\n- #define POCKETFFT_NAMESPACE itk::detail::pocketfft\n- #define POCKETFFT_CACHE_SIZE 16"]
    pocketfft_hdronly["itkpocketfft/pocketfft_hdronly.h\n(vendored upstream)"]
    system_pocketfft["<pocketfft_hdronly.h>\n(system, if ITK_USE_SYSTEM_POCKETFFT=ON)"]
    filters["PocketFFT filter headers\n(itkPocketFFTCommon.h, etc.)"]
    vnl["vnl_fft_1d.h\n(deprecated shim)"]

    ITKFFT -->|DEPENDS| ITKPocketFFT
    ITKPocketFFT --> itk_pocketfft_h
    itk_pocketfft_h -->|vendored default| pocketfft_hdronly
    itk_pocketfft_h -->|ITK_USE_SYSTEM_POCKETFFT=ON| system_pocketfft
    filters -->|#include| itk_pocketfft_h
    vnl -->|#include| itk_pocketfft_h
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    ITKFFT["ITKFFT module\n(itk-module.cmake)"]
    ITKPocketFFT["ITKPocketFFT module\n(ThirdParty)"]
    itk_pocketfft_h["itk_pocketfft.h\n(generated via configure_file)\n- #define POCKETFFT_NAMESPACE itk::detail::pocketfft\n- #define POCKETFFT_CACHE_SIZE 16"]
    pocketfft_hdronly["itkpocketfft/pocketfft_hdronly.h\n(vendored upstream)"]
    system_pocketfft["<pocketfft_hdronly.h>\n(system, if ITK_USE_SYSTEM_POCKETFFT=ON)"]
    filters["PocketFFT filter headers\n(itkPocketFFTCommon.h, etc.)"]
    vnl["vnl_fft_1d.h\n(deprecated shim)"]

    ITKFFT -->|DEPENDS| ITKPocketFFT
    ITKPocketFFT --> itk_pocketfft_h
    itk_pocketfft_h -->|vendored default| pocketfft_hdronly
    itk_pocketfft_h -->|ITK_USE_SYSTEM_POCKETFFT=ON| system_pocketfft
    filters -->|#include| itk_pocketfft_h
    vnl -->|#include| itk_pocketfft_h
Loading

Reviews (1): Last reviewed commit: "ENH: Vendor pocketfft as the ITKPocketFF..." | Re-trigger Greptile

Comment thread Modules/ThirdParty/PocketFFT/src/itkpocketfft/LICENSE.md
Comment thread Modules/ThirdParty/PocketFFT/src/itk_pocketfft.h.in

@dzenanz dzenanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good.

Comment thread Modules/ThirdParty/PocketFFT/CMakeLists.txt
@blowekamp blowekamp self-requested a review June 30, 2026 19:57
Move the header-only pocketfft from the FFT module include directory into
a proper third-party module, Modules/ThirdParty/PocketFFT, vendored from the
InsightSoftwareConsortium/pocketfft fork via UpdateFromUpstream.sh.

itk_pocketfft.h is the single entry point: it is the only header that
includes pocketfft_hdronly.h, applies ITK's POCKETFFT_NAMESPACE
(itk::detail::pocketfft) and POCKETFFT_CACHE_SIZE (16), and exposes the
itk::pocketfft alias.  The vendored copy keeps upstream defaults so the fork
stays a faithful mirror.  ITKFFT now DEPENDS ITKPocketFFT; the deprecated
vnl_fft_1d shim routes through itk_pocketfft.h.
@hjmjohnson hjmjohnson force-pushed the thirdparty-pocketfft-vendor branch from 3e71196 to a4de8b3 Compare June 30, 2026 22:29
@hjmjohnson hjmjohnson merged commit a879f35 into InsightSoftwareConsortium:main Jul 1, 2026
19 of 21 checks passed
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 area:ThirdParty Issues affecting the ThirdParty module type:Enhancement Improvement of existing methods or implementation type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants