Skip to content

feat(hipfft): add the generated Fortran bindings for hipFFT and hipFFTW in bindings/fortran/hipfft - #12367

Draft
amontoison wants to merge 12 commits into
ROCm:developfrom
amontoison:users/amontoison/hipfft-fortran-bindings
Draft

amontoison wants to merge 12 commits into
ROCm:developfrom
amontoison:users/amontoison/hipfft-fortran-bindings

Conversation

@amontoison

@amontoison amontoison commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Implements RFC0015, Fortran Bindings Split (update) for hipFFT: bindings/fortran/hipfft/ is a standalone CMake project that builds the generated Fortran binding against an installed hipFFT. The library is untouched: no option, no add_subdirectory, no change to projects/hipfft/.

Draft until ROCm/rocm-systems#11923 (HIP Fortran binding, which the tests use) merges.

What lands

  • The hipFFT API split as CUDA Fortran's cufft and cufftXt modules, so that use cufftXt hipifies to use hipfftxt. Generated from the hipFFT headers with feat(hipfft): bind the Xt and Mp API in a hipfftxt module beside hipfft rocm-fortran-generator#17 (not merged yet) and marked linguist-generated:
    • bindings/fortran/hipfft/hipfft.F90 (1 683 lines): module hipfft, the hipfft* functions of hipfft.h, with the enum constants, the hipfftCheck helper and array overloads.
    • bindings/fortran/hipfft/hipfftxt.F90 (651 lines): module hipfftxt, every hipfftXt* and hipfftMp* function, as in CUDA Fortran's cufftXt (so hipfftXtSetWorkArea too, although hipfft.h declares it), with the Xt enums and the hipXtDesc / hipLibXtDesc types of hiplibxt.h. It uses hipfft and re-exports it, so use hipfftxt alone gives the whole API, as #include <hipfft/hipfftXt.h> does in C. Fortran is case-insensitive, so use hipfftXt works too.
    • bindings/fortran/hipfft/hipfftw.F90 (3 021 lines): the FFTW3-compatible module hipfftw, from hipfftw.h, with the FFTW_* flags and the fftw_iodim / fftw_iodim64 types.
  • metadata/hipfft.toml, metadata/hipfftxt.toml, metadata/hipfftw.toml: the generator metadata they were generated with.
  • test/: 36 CTest tests, 23 .f03 tests of the C interfaces and 13 .f08 tests of the array overloads (registered as <name>_f2008). hipfft_xt_descriptor_z skips (return code 77) on fewer than two GPUs. They also install: the executables in bin/, and a CTestTestfile.cmake with the same tests and properties in bin/hipfft-fortran/, for ctest --test-dir.
  • hipfft and hipfftxt build into one archive, libhipfft_fortran.a (target hip::hipfft_fortran, package hipfft-fortran). hipfftw does not use hipfft, so it has its own target (hip::hipfftw_fortran), archive and config package (hipfftw-fortran); both build together.
  • CMakeLists.txt, the hipfft-fortran and hipfftw-fortran config templates, cmake/ROCmFortranCompiler.cmake (the same in every binding: ROCm's amdflang is preferred over the first compiler on PATH unless CMAKE_Fortran_COMPILER or FC is set), cmake/toolchains/ and the binding's CHANGELOG.md.
  • .github/CODEOWNERS: /bindings/fortran/hipfft/ @ROCm/rocm-fortran-maintainers @ROCm/fft-reviewers.
  • .github/repos-config.json: a bindings/fortran entry, so CI detects changes to the binding. Each binding PR appends its entry at the end of the list, so all but the first to merge need a trivial rebase.

A consumer uses find_package(hipfft-fortran) or find_package(hipfftw-fortran) and links hip::hipfft_fortran or hip::hipfftw_fortran. The archive and .mod files install per compiler under lib/fortran/<compiler>/ and include/fortran/<compiler>/; HIPFFT_FORTRAN_COMPILER_DIR names that directory. The archive has one section per procedure, so a program linked with -Wl,--gc-sections keeps only the wrappers it calls.

Options

Option Default Effect
BUILD_FORTRAN_BINDINGS ${UNIX} builds the binding; skipped without a Fortran compiler
BUILD_FORTRAN_CLIENTS ON builds and installs the tests in test/; off under BUILD_ADDRESS_SANITIZER
FORTRAN_ARRAY_INTERFACES assumed-shape none / assumed-shape / assumed-rank array overloads

In TheRock

ROCm/TheRock#9446 builds bindings/fortran/hipfft as the hipfft-fortran subproject against the hipFFT it built, with -DBUILD_FORTRAN_BINDINGS=ON -DBUILD_FORTRAN_CLIENTS=${THEROCK_BUILD_TESTING}, ships it in the fft-fortran artifact and runs the installed tests in its hipfft-fortran GPU test job.

Follow-ups

hipFFT never shipped a Fortran module, so there is nothing to deprecate.

Build and test

From the repository root, with $PREFIX the install prefix:

lib=hipfft
cmake -S bindings/fortran/$lib -B build/$lib-fortran \
  -DCMAKE_PREFIX_PATH="/opt/rocm;$HIP_FORTRAN_PREFIX" -DCMAKE_INSTALL_PREFIX="$PREFIX"
cmake --build build/$lib-fortran
ctest --test-dir build/$lib-fortran
cmake --install build/$lib-fortran
ctest --test-dir "$PREFIX/bin/$lib-fortran"

$HIP_FORTRAN_PREFIX holds the HIP Fortran binding (hip-fortran) built with the same compiler; without it the tests are skipped.

Verification

Standalone against ROCm 10.1 on one GPU, with amdflang and with gfortran: 36 tests, 35 pass, 1 skipped. From the install tree, ctest --test-dir $PREFIX/bin/hipfft-fortran gives the same result.

JIRA ID: ROCM-31390

@therock-pr-bot

therock-pr-bot Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass PR does not contain code files — Unit Test auto-passed
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

@codecov

codecov Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #12367      +/-   ##
===========================================
+ Coverage    75.95%   75.97%   +0.02%     
===========================================
  Files         2880     2880              
  Lines       479025   478959      -66     
  Branches     71958    71942      -16     
===========================================
+ Hits        363828   363852      +24     
+ Misses       90338    90255      -83     
+ Partials     24859    24852       -7     
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 48.93% <ø> (ø) Carriedforward from 38cb114
TensileLite-Unit 83.68% <ø> (ø) Carriedforward from 38cb114
hipBLAS 90.62% <ø> (ø) Carriedforward from 38cb114
hipBLASLt 64.43% <ø> (ø) Carriedforward from 38cb114
hipCUB 82.68% <ø> (ø) Carriedforward from 38cb114
hipDNN 86.78% <ø> (ø) Carriedforward from 38cb114
hipFFT 43.09% <ø> (+1.09%) ⬆️
hipRAND 76.12% <ø> (ø) Carriedforward from 38cb114
hipSOLVER 69.67% <ø> (ø) Carriedforward from 38cb114
hipSPARSE 86.99% <ø> (ø) Carriedforward from 38cb114
rocBLAS 68.73% <ø> (ø) Carriedforward from 38cb114
rocFFT 48.10% <ø> (ø) Carriedforward from 38cb114
rocRAND 57.30% <ø> (ø) Carriedforward from 38cb114
rocSOLVER 76.74% <ø> (ø) Carriedforward from 38cb114
rocSPARSE 76.92% <ø> (ø) Carriedforward from 38cb114
rocThrust 93.15% <ø> (ø) Carriedforward from 38cb114

*This pull request uses carry forward flags. Click here to find out more.
see 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@amontoison
amontoison force-pushed the users/amontoison/hipfft-fortran-bindings branch from 4bf4b89 to 43aeb34 Compare September 25, 2026 04:38
@amontoison
amontoison force-pushed the users/amontoison/hipfft-fortran-bindings branch 2 times, most recently from 9b809e5 to 0b8436e Compare September 28, 2026 03:49
@amontoison
amontoison force-pushed the users/amontoison/hipfft-fortran-bindings branch from 0b8436e to 1b60747 Compare September 29, 2026 03:14
@amontoison
amontoison force-pushed the users/amontoison/hipfft-fortran-bindings branch from 9c09f06 to dc432d8 Compare October 4, 2026 03:45
@amontoison amontoison changed the title feat(hipfft): add generated Fortran bindings for hipFFT and hipFFTW (RFC0014) feat(hipfft): add generated Fortran bindings for hipFFT and hipFFTW Oct 4, 2026
@amontoison
amontoison force-pushed the users/amontoison/hipfft-fortran-bindings branch from dc432d8 to 71f5001 Compare October 5, 2026 05:13
Add fortran/hipfft.F90 and fortran/hipfftw.F90, the hipfft and hipfftw
modules generated from the C headers by the rocm-fortran generator
under RFC0019 (ROCm/TheRock#8122). They are committed next to the
headers, are not edited by hand, and .gitattributes marks them
linguist-generated.
@amontoison
amontoison force-pushed the users/amontoison/hipfft-fortran-bindings branch 4 times, most recently from 44e940a to 80d81b3 Compare October 22, 2026 15:31
Build fortran/hipfft.F90 and fortran/hipfftw.F90 as hip::hipfft_fortran
and hip::hipfftw_fortran from fortran/, a CMake project of its own that
the root adds. BUILD_FORTRAN_BINDINGS (default ${UNIX}, OFF on the CUDA
backend), BUILD_FORTRAN_CLIENTS (default ON) and
FORTRAN_ARRAY_INTERFACES (default assumed-shape, hipfft only) control
them, and HIPFFT_BUILD_FORTRAN_* and HIPFFTW_BUILD_FORTRAN_* override
per binding. The .mod files and the archives install per compiler under
<includedir>/fortran/<compiler> and <libdir>/fortran/<compiler>, beside
hipfft-fortran and hipfftw-fortran config packages.

fortran/test/ adds 20 CTest tests labelled gpu; they use hip and skip
until ROCm/rocm-systems#11923 lands. hipFFT had no Fortran module
before, so nothing is removed.

Refs: ROCm/TheRock#8122 (RFC0019)
@amontoison
amontoison force-pushed the users/amontoison/hipfft-fortran-bindings branch from 80d81b3 to 9f54e86 Compare October 22, 2026 18:14
The hipFFT Fortran binding consumes hipFFT's public API and builds
standalone against an installed hipFFT, so it moves out of the library
into bindings/fortran/hipfft, the tree every monorepo and TheRock use for
the Fortran bindings (RFC0015). Nothing is wired into the library build
any more: the library is back to its state on develop.

- bindings/fortran/hipfft reads hipFFT's version from projects/hipfft
- the binding has its own .gitattributes and CHANGELOG.md
- CODEOWNERS: /bindings/fortran/hipfft/, same owners
- repos-config.json: register bindings/fortran/hipfft so CI detects changes
@github-actions github-actions Bot added github actions project: none Does not target any component labels Nov 3, 2026
@amontoison amontoison changed the title feat(hipfft): add generated Fortran bindings for hipFFT and hipFFTW feat(hipfft): add the generated Fortran bindings for hipFFT and hipFFTW in bindings/fortran/hipfft Nov 3, 2026
Regenerate bindings/fortran/hipfft with rocm-fortran-generator 9c8b3e4, and
commit its metadata in bindings/fortran/hipfft/metadata/, where the generator
reads it from a checkout, instead of the copy kept in the generator.
Install the test executables in bin/, and a CTestTestfile.cmake in
bin/hipfft-fortran/ with the same tests and properties as the build tree,
so that ctest --test-dir runs them from an install, as TheRock's test
jobs do for the libraries.
The binding is built against an installed hipFFT and is never added to the
library's build, so drop what only served that: the per-library
BUILD_FORTRAN_* overrides, the PARENT_SCOPE results, the ROCM_HAVE_FORTRAN
shortcut, the gating on the library's client and test options, and the
comments about the root. Find the Fortran compiler through the
cmake/ROCmFortranCompiler.cmake shared by all the bindings, and require
CMake 3.19.

The binding targets the ROCm backend only, so BUILD_FORTRAN_BINDINGS no longer
defaults to OFF on the CUDA backend. Without the HIPFFT_* and HIPFFTW_*
overrides, both modules build together.
…modules

One module per C header, as CUDA Fortran's cufft and cufftXt, so that
`use cufftXt` hipifies to `use hipfftxt`: hipfft holds hipfft.h, and hipfftxt
holds hipfftXt.h and hipfftMp.h. hipfftxt uses hipfft, so `use hipfftxt` alone
gives the whole API. Both build into libhipfft_fortran.a (hip::hipfft_fortran),
and the Xt and Mp metadata moves to metadata/hipfftxt.toml.

Regenerated with ROCm/rocm-fortran-generator#17.
Every hipfftXt* and hipfftMp* function is now in hipfftxt, as cufftXtSetWorkArea
is in CUDA Fortran's cufftXt module, although hipfft.h declares
hipfftXtSetWorkArea. Regenerated with ROCm/rocm-fortran-generator#17.
…ortran and lib/cmake/hipfftw-fortran

The package files went to lib/cmake/hipfft, the C library's directory, with a forwarder in lib/cmake/hipfft-fortran and lib/cmake/hipfftw-fortran. rocRAND and hipRAND install their own legacy <lib>-fortran-config.cmake there, so the files overlapped. Install the config, targets and version files directly where find_package(<package>) looks, as the HIP and ROCTx bindings do, and drop the forwarder.
… recursion

rocm-cmake's generated hipfft-config.cmake is to include
lib/cmake/hipfft-fortran/hipfft-fortran-config.cmake after its targets
(ROCm/rocm-cmake#303). Skip find_dependency(hipfft) when hipfft is the
package being found, not only when hip::hipfft (hip::hipfftw for
hipfftw-fortran) is already imported, so that include never re-enters
hipfft-config.cmake.
hipFFTW is built and exported with hipFFT, so hipfft-config.cmake defines
both hip::hipfft and hip::hipfftw. hipfft-fortran-config.cmake now includes
hipfftw-fortran-config.cmake when installed, so find_package(hipfft) (through
the rocm-cmake hook) and find_package(hipfft-fortran) also give
hip::hipfftw_fortran. The include is optional and its failure only sets
hipfftw-fortran_* variables, so hipfft-fortran is still found without it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant