Repository navigation
docs(rfcs): add RFC0015 for distributing Fortran bindings across rocm-systems and rocm-libraries - #8122
Merged
Conversation
✅ All Checks Passed — Ready for Review
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🎉 All checks passed! This PR is ready for review. |
amontoison
marked this pull request as ready for review
September 10, 2026 05:24
saadrahim
reviewed
Sep 10, 2026
saadrahim
approved these changes
Sep 10, 2026
saadrahim
left a comment
Member
There was a problem hiding this comment.
Will need stakeholder review across ROCm Core, looks good from product.
saadrahim
requested review from
bobbyphilip-amd,
ddembeckAMD and
dennyiriawan
September 10, 2026 16:46
This was referenced Sep 21, 2026
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 21, 2026
rocfft.F90 is generated from the rocFFT public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocfft`, carrying the interfaces, the enum constants, the opaque handles and the rocfftCheck status helper. A consumer writes one `use rocfft`. Implements RFC0014 (ROCm/TheRock#8122) for rocFFT, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: a Fortran binding declares bind(C) interfaces only, so it compiles against neither the rocFFT headers nor librocfft, and needs no GPU and no HIP compiler to build. librocfft is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCFFT_BUILD_FORTRAN_* so one library can be singled out in a monorepo build. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCFFT_HAVE_FORTRAN_BINDINGS reports whether they were really built, and the config package sets rocfft_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, which is the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, Flang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper, where a plain basename would not. The config package lands in lib/cmake/rocfft beside the C package, and a forwarder in lib/cmake/rocfft-fortran makes find_package(rocfft-fortran) resolve to the same place. Tests ----- test/ carries 19 tests under CTest. Eighteen are runtime tests that allocate device memory, so they write `use hip` next to `use rocfft` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_rocfft.F03, the exhaustive symbol test, uses only iso_c_binding and rocfft, so it is registered outside that guard. That distinction is load-bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against librocfft. Runtime tests are labelled "gpu" and the symbol test "symbols", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with gfortran 13.3.0. Against a stock /opt/rocm the symbol test builds, links and passes on its own. With the HIP Fortran binding available, 19 of 19 pass; one of those, field_brick_z, prints SKIPPED and exits 0 because it wants two GPUs, so the honest reading is 17 real GPU tests, 1 self-skip and the symbol test. The documented consumer path was exercised end to end: install, find_package(rocfft-fortran), link roc::rocfft_fortran, run on the GPU.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 21, 2026
hipfft.F90 and hipfftw.F90 are generated from the public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. Each is a single self-contained module, `hipfft` and `hipfftw`, carrying the interfaces, the enum constants, the opaque handles and the status helper. A consumer writes one `use hipfft`. Implements RFC0014 (ROCm/TheRock#8122) for hipFFT, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Two bindings in one directory, because hipFFTW is built by the hipFFT project rather than one of its own. They are separate modules, separate targets and separate config packages, but they live next to the headers they bind rather than in a directory of their own. The bindings declare bind(C) interfaces only, so they compile against neither the hipFFT headers nor libhipfft, and need no GPU and no HIP compiler to build. The C libraries are link-time dependencies of a final executable and are carried as each target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPFFT_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. The config packages set hipfft_FORTRAN_FOUND and hipfftw_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so each .mod and archive installs under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper, where a plain basename would not. Both config packages land in lib/cmake/hipfft beside the C package, and forwarders in lib/cmake/hipfft-fortran and lib/cmake/hipfftw-fortran make find_package(hipfft-fortran) and find_package(hipfftw-fortran) resolve to the same place. Tests ----- test/ carries 21 tests under CTest. Nineteen are runtime tests that allocate device memory, so they write `use hip` next to their own `use`, which makes the HIP Fortran binding a compile-time dependency; they are skipped with a named message when it is absent. The two exhaustive symbol tests use only iso_c_binding and the module under test, so they are registered outside that guard. That distinction matters: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only ones that prove every bind(C) symbol resolves against the installed libraries. Runtime tests are labelled "gpu" and the symbol tests "symbols", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with BOTH compilers, gfortran 13.3.0 and amdflang 23.0.0. Against a stock /opt/rocm the two symbol tests build, link and pass on their own; with the HIP Fortran binding available, 21 of 21 pass. The documented consumer path was exercised end to end with amdflang: install, find_package on both packages, link hip::hipfft_fortran and hip::hipfftw_fortran in one program, run on the GPU. The compiler-mismatch diagnostic was exercised for real by installing with amdflang and consuming with gfortran, which is what confirms the CMAKE_Fortran_COMPILER_ID mapping handles LLVMFlang and that the message renders as prose rather than as a semicolon-separated list.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 21, 2026
hipsparse.F90 is generated from the hipSPARSE public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hipsparse`, carrying the interfaces, the enum constants, the opaque handles and the hipsparseCheck status helper. A consumer writes one `use hipsparse`. Implements RFC0014 (ROCm/TheRock#8122) for hipSPARSE, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: it compiles against neither the hipSPARSE headers nor libhipsparse, and needs no GPU to build. libhipsparse is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Target naming ------------- hipSPARSE already creates a target called hipsparse_fortran: the hand-written Fortran layer for its own test clients, under HIPSPARSE_ENABLE_FORTRAN. CMake target names are global, so the generated binding is built as hipsparse_fortran_bindings and given EXPORT_NAME hipsparse_fortran. Consumers therefore still write roc::hipsparse_fortran and link libhipsparse_fortran.a, exactly as the other libraries, while the two targets coexist in one build tree. The hand-written layer is untouched: the generated module is not yet source-compatible with it, so superseding it is a separate coordinated change. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPSPARSE_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. HIPSPARSE_HAVE_FORTRAN_BINDINGS reports whether they were really built, and the config package sets hipsparse_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. The config package lands in lib/cmake/hipsparse beside the C package, and a forwarder in lib/cmake/hipsparse-fortran makes find_package(hipsparse-fortran) resolve to the same place. Tests ----- test/ carries 50 tests under CTest. Forty-nine are runtime tests that allocate device memory around each hipSPARSE call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_hipsparse.F03, the exhaustive symbol test, uses only iso_c_binding and hipsparse, so it is registered outside that guard. That distinction is load-bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against libhipsparse. The generated sources are named hipsparse_<op>.f03, so the library name is stripped when composing the CMake and CTest identifiers: the test is hipsparse_fortran_dspmv rather than hipsparse_fortran_hipsparse_dspmv. The source files are untouched. Runtime tests are labelled "gpu" and the symbol test "symbols", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with BOTH compilers, gfortran 13.3.0 and amdflang 23.0.0. A standalone configure is clean under -Wdev. Against a stock /opt/rocm the symbol test builds, links and passes on its own; with the HIP Fortran binding available, 50 of 50 pass with each compiler. The documented consumer path was exercised end to end with amdflang: install, find_package(hipsparse-fortran), link roc::hipsparse_fortran, run on the GPU. The compiler-mismatch diagnostic was exercised for real by installing with amdflang and consuming with gfortran, which is what confirms the CMAKE_Fortran_COMPILER_ID mapping handles LLVMFlang and that the message renders as prose rather than as a semicolon-separated list.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 21, 2026
JIRA ID : ROCM-31390 hipblas.F90 is generated from the hipBLAS public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hipblas`, carrying the interfaces, the enum constants, the opaque handles and the hipblasCheck status helper. A consumer writes one `use hipblas`. Implements RFC0014 (ROCm/TheRock#8122) for hipBLAS, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: it compiles against neither the hipBLAS headers nor libhipblas, and needs no GPU to build. libhipblas is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. The hook sits outside the SKIP_LIBRARY guard: that guard controls whether libhipblas is built here, and the bindings need it linked, not built. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPBLAS_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. HIPBLAS_HAVE_FORTRAN_BINDINGS reports whether they were really built, and the config package sets hipblas_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides HIPBLAS_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. A strict equality would reject exactly the sites that used the documented override. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. CMake has no regex-escape. The config package lands in lib/cmake/hipblas beside the C package, and a forwarder in lib/cmake/hipblas-fortran makes find_package(hipblas-fortran) resolve to the same place. Tests ----- test/ carries 69 tests under CTest. Sixty-eight are runtime tests that allocate and copy device memory around each hipBLAS call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_hipblas.F03, the exhaustive symbol test, uses only iso_c_binding and hipblas, so it is registered outside that guard. That distinction is load-bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against libhipblas. Runtime tests are labelled "gpu" and the symbol test "symbols", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with BOTH compilers, gfortran 13.3.0 and amdflang 23.0.0. A standalone configure is clean under -Wdev. Against a stock /opt/rocm the symbol test builds, links and passes on its own; with the HIP Fortran binding available, 69 of 69 pass. The documented consumer path was exercised end to end with amdflang: install, find_package(hipblas-fortran), link roc::hipblas_fortran, run on the GPU. The compiler check was exercised in both directions rather than only the happy one. Installed under an overridden gfortran-13.3.0 directory, a gfortran consumer is accepted; an amdflang consumer against that same install is rejected with a named diagnostic. Installing with amdflang and consuming with gfortran is what confirms the CMAKE_Fortran_COMPILER_ID mapping handles LLVMFlang, and that the message renders as prose rather than as a semicolon-separated list.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 21, 2026
JIRA ID : ROCM-31390 hipblas.F90 is generated from the hipBLAS public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hipblas`, carrying the interfaces, the enum constants, the opaque handles and the hipblasCheck status helper. A consumer writes one `use hipblas`. Implements RFC0014 (ROCm/TheRock#8122) for hipBLAS, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: it compiles against neither the hipBLAS headers nor libhipblas, and needs no GPU to build. libhipblas is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. The hook sits outside the SKIP_LIBRARY guard: that guard controls whether libhipblas is built here, and the bindings need it linked, not built. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPBLAS_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. HIPBLAS_HAVE_FORTRAN_BINDINGS reports whether they were really built, and the config package sets hipblas_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides HIPBLAS_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. A strict equality would reject exactly the sites that used the documented override. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. CMake has no regex-escape. The config package lands in lib/cmake/hipblas beside the C package, and a forwarder in lib/cmake/hipblas-fortran makes find_package(hipblas-fortran) resolve to the same place. Tests ----- test/ carries 69 tests under CTest. Sixty-eight are runtime tests that allocate and copy device memory around each hipBLAS call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_hipblas.F03, the exhaustive symbol test, uses only iso_c_binding and hipblas, so it is registered outside that guard. That distinction is load-bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against libhipblas. Runtime tests are labelled "gpu" and the symbol test "symbols", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with BOTH compilers, gfortran 13.3.0 and amdflang 23.0.0. A standalone configure is clean under -Wdev. Against a stock /opt/rocm the symbol test builds, links and passes on its own; with the HIP Fortran binding available, 69 of 69 pass. The documented consumer path was exercised end to end with amdflang: install, find_package(hipblas-fortran), link roc::hipblas_fortran, run on the GPU. The compiler check was exercised in both directions rather than only the happy one. Installed under an overridden gfortran-13.3.0 directory, a gfortran consumer is accepted; an amdflang consumer against that same install is rejected with a named diagnostic. Installing with amdflang and consuming with gfortran is what confirms the CMAKE_Fortran_COMPILER_ID mapping handles LLVMFlang, and that the message renders as prose rather than as a semicolon-separated list.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 24, 2026
JIRA ID : ROCM-31390 rocrand.F90 is generated from the rocRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocrand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the rocrandCheck status helper. A consumer writes one `use rocrand`. Implements RFC0014 (ROCm/TheRock#8122) for rocRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: it compiles against neither the rocRAND headers nor librocrand, and needs no GPU to build. librocrand is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. The hook sits outside the USE_SYSTEM_LIB branch: that branch controls whether librocrand is built here, and the bindings need it linked, not built. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCRAND_HAVE_FORTRAN_BINDINGS reports whether they were really built. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides ROCRAND_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. A strict equality would reject exactly the sites that used the documented override. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. Coexistence with the deprecated wrapper --------------------------------------- rocRAND already ships a hand-written wrapper (library/src/fortran/rocrand_m.f90) under BUILD_FORTRAN_WRAPPER, itself deprecated in favour of hipfort. It is left untouched here, and it collides with these bindings in two places. The target name is the first. Both want rocrand_fortran, which is a hard CMake error naming neither option, so the clash is reported here instead, with the flag to turn off. It is not resolved by silently winning: a site that asked for BUILD_FORTRAN_WRAPPER asked for the wrapper. The config file name is the second, and it is why this package does not use the layout the other libraries use. lib/cmake/rocrand/rocrand-fortran-config.cmake already belongs to the wrapper, and rocrand-config.cmake include()s that name unconditionally -- it is in /opt/rocm today. Installing there would not shadow a stale file, it would splice this package into the middle of every find_package(rocrand) in existence, C++ consumers included, and drop rocrand_FORTRAN_SRC_DIRS with it. So the real config stands alone in lib/cmake/rocrand-fortran, which find_package(rocrand-fortran) already searches, and nothing is written into lib/cmake/rocrand. For the same reason the package reports rocrand_FORTRAN_BINDINGS_FOUND rather than overloading rocrand_FORTRAN_FOUND, which the wrapper's config defines with a different meaning. When the wrapper is retired, both can move to the shared spelling. Tests ----- 24 tests under CTest, off by default. Twenty-three are runtime tests, one per (generator, distribution) pair, that allocate and copy device memory around each rocRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_rocrand.F03, the exhaustive symbol test, uses only iso_c_binding and rocrand, so it is registered outside that guard, behind BUILD_FORTRAN_EXTENDED_TESTS. That distinction is load bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against librocrand. Runtime tests are labelled gpu and the symbol test symbols, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 24, 2026
JIRA ID : ROCM-31390 hiprand.F90 is generated from the hipRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hiprand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the hiprandCheck status helper. A consumer writes one `use hiprand`. Implements RFC0014 (ROCm/TheRock#8122) for hipRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: it compiles against neither the hipRAND headers nor libhiprand, and needs no GPU to build. libhiprand is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. HIPRAND_HAVE_FORTRAN_BINDINGS reports whether they were really built. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides HIPRAND_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. A strict equality would reject exactly the sites that used the documented override. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. Coexistence with the deprecated wrapper --------------------------------------- hipRAND already ships a hand-written wrapper (library/src/fortran/hiprand_m.f90) under BUILD_FORTRAN_WRAPPER, itself deprecated in favour of hipfort. It is left untouched here, and it collides with these bindings in two places. The target name is the first. Both want hiprand_fortran, which is a hard CMake error naming neither option, so the clash is reported here instead, with the flag to turn off. It is not resolved by silently winning: a site that asked for BUILD_FORTRAN_WRAPPER asked for the wrapper. The config file name is the second, and it is why this package does not use the layout the other libraries use. lib/cmake/hiprand/hiprand-fortran-config.cmake already belongs to the wrapper, and hiprand-config.cmake include()s that name unconditionally -- it is in /opt/rocm today. Installing there would not shadow a stale file, it would splice this package into the middle of every find_package(hiprand) in existence, C++ consumers included, and drop hiprand_FORTRAN_SRC_DIRS with it. So the real config stands alone in lib/cmake/hiprand-fortran, which find_package(hiprand-fortran) already searches, and nothing is written into lib/cmake/hiprand. For the same reason the package reports hiprand_FORTRAN_BINDINGS_FOUND rather than overloading hiprand_FORTRAN_FOUND, which the wrapper's config defines with a different meaning. When the wrapper is retired, both can move to the shared spelling. Tests ----- 24 tests under CTest, off by default. Twenty-three are runtime tests, one per (generator, distribution) pair, that allocate and copy device memory around each hipRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_hiprand.F03, the exhaustive symbol test, uses only iso_c_binding and hiprand, so it is registered outside that guard, behind BUILD_FORTRAN_EXTENDED_TESTS. That distinction is load bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against libhiprand. Runtime tests are labelled gpu and the symbol test symbols, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 24, 2026
JIRA ID : ROCM-31390 rocrand.F90 is generated from the rocRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocrand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the rocrandCheck status helper. A consumer writes one `use rocrand`. Implements RFC0014 (ROCm/TheRock#8122) for rocRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: it compiles against neither the rocRAND headers nor librocrand, and needs no GPU to build. librocrand is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. The hook sits outside the USE_SYSTEM_LIB branch: that branch controls whether librocrand is built here, and the bindings need it linked, not built. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCRAND_HAVE_FORTRAN_BINDINGS reports whether they were really built. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides ROCRAND_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. A strict equality would reject exactly the sites that used the documented override. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. Coexistence with the deprecated wrapper --------------------------------------- rocRAND already ships a hand-written wrapper (library/src/fortran/rocrand_m.f90) under BUILD_FORTRAN_WRAPPER, itself deprecated in favour of hipfort. It is left untouched here, and it collides with these bindings in two places. The target name is the first. Both want rocrand_fortran, which is a hard CMake error naming neither option, so the clash is reported here instead, with the flag to turn off. It is not resolved by silently winning: a site that asked for BUILD_FORTRAN_WRAPPER asked for the wrapper. The config file name is the second, and it is why this package does not use the layout the other libraries use. lib/cmake/rocrand/rocrand-fortran-config.cmake already belongs to the wrapper, and rocrand-config.cmake include()s that name unconditionally -- it is in /opt/rocm today. Installing there would not shadow a stale file, it would splice this package into the middle of every find_package(rocrand) in existence, C++ consumers included, and drop rocrand_FORTRAN_SRC_DIRS with it. So the real config stands alone in lib/cmake/rocrand-fortran, which find_package(rocrand-fortran) already searches, and nothing is written into lib/cmake/rocrand. For the same reason the package reports rocrand_FORTRAN_BINDINGS_FOUND rather than overloading rocrand_FORTRAN_FOUND, which the wrapper's config defines with a different meaning. When the wrapper is retired, both can move to the shared spelling. Tests ----- 24 tests under CTest, off by default. Twenty-three are runtime tests, one per (generator, distribution) pair, that allocate and copy device memory around each rocRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_rocrand.F03, the exhaustive symbol test, uses only iso_c_binding and rocrand, so it is registered outside that guard, behind BUILD_FORTRAN_EXTENDED_TESTS. That distinction is load bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against librocrand. Runtime tests are labelled gpu and the symbol test symbols, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 24, 2026
JIRA ID : ROCM-31390 hiprand.F90 is generated from the hipRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hiprand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the hiprandCheck status helper. A consumer writes one `use hiprand`. Implements RFC0014 (ROCm/TheRock#8122) for hipRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: it compiles against neither the hipRAND headers nor libhiprand, and needs no GPU to build. libhiprand is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. HIPRAND_HAVE_FORTRAN_BINDINGS reports whether they were really built. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides HIPRAND_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. A strict equality would reject exactly the sites that used the documented override. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. Coexistence with the deprecated wrapper --------------------------------------- hipRAND already ships a hand-written wrapper (library/src/fortran/hiprand_m.f90) under BUILD_FORTRAN_WRAPPER, itself deprecated in favour of hipfort. It is left untouched here, and it collides with these bindings in two places. The target name is the first. Both want hiprand_fortran, which is a hard CMake error naming neither option, so the clash is reported here instead, with the flag to turn off. It is not resolved by silently winning: a site that asked for BUILD_FORTRAN_WRAPPER asked for the wrapper. The config file name is the second, and it is why this package does not use the layout the other libraries use. lib/cmake/hiprand/hiprand-fortran-config.cmake already belongs to the wrapper, and hiprand-config.cmake include()s that name unconditionally -- it is in /opt/rocm today. Installing there would not shadow a stale file, it would splice this package into the middle of every find_package(hiprand) in existence, C++ consumers included, and drop hiprand_FORTRAN_SRC_DIRS with it. So the real config stands alone in lib/cmake/hiprand-fortran, which find_package(hiprand-fortran) already searches, and nothing is written into lib/cmake/hiprand. For the same reason the package reports hiprand_FORTRAN_BINDINGS_FOUND rather than overloading hiprand_FORTRAN_FOUND, which the wrapper's config defines with a different meaning. When the wrapper is retired, both can move to the shared spelling. Tests ----- 24 tests under CTest, off by default. Twenty-three are runtime tests, one per (generator, distribution) pair, that allocate and copy device memory around each hipRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_hiprand.F03, the exhaustive symbol test, uses only iso_c_binding and hiprand, so it is registered outside that guard, behind BUILD_FORTRAN_EXTENDED_TESTS. That distinction is load bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against libhiprand. Runtime tests are labelled gpu and the symbol test symbols, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 24, 2026
JIRA ID : ROCM-31390 rocrand.F90 is generated from the rocRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocrand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the rocrandCheck status helper. A consumer writes one `use rocrand` and links roc::rocrand_fortran. Implements RFC0014 (ROCm/TheRock#8122) for rocRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written wrapper --------------------------------- library/src/fortran (rocrand_m.f90, hip_m.f90), its config template, and the FRUIT-based suite under test/fortran go with it, along with BUILD_FORTRAN_WRAPPER and its references in the top-level CMakeLists, library/CMakeLists.txt, test/CMakeLists.txt, cmake/Summary.cmake, cmake/Dependencies.cmake and docs/install/build.rst. That API was deprecated in favour of hipfort in rocRAND 4.0.0 / ROCm 7.0 and has never been shipped enabled: ROCm builds with BUILD_FORTRAN_WRAPPER=OFF, so in an installed /opt/rocm rocrand_FORTRAN_FOUND is NOTFOUND, rocrand_FORTRAN_SRC_DIRS is never set, and rocrand/src/fortran does not exist. No consumer of a ROCm package can therefore be using it; only a source build that passed the flag. Removing it also frees two names the generated bindings want. The target rocrand_fortran was defined by both, which is a hard CMake error. More importantly lib/cmake/rocrand/rocrand-fortran-config.cmake belonged to the wrapper, and rocrand-config.cmake include()s that name unconditionally, so the new package could not have been co-installed beside the C one while the wrapper stood. With the wrapper gone, rocRAND uses the same layout as the rest of the series: the real config in lib/cmake/rocrand, a forwarder in lib/cmake/rocrand-fortran, and rocrand_FORTRAN_FOUND back to its ordinary meaning. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCRAND_HAVE_FORTRAN_BINDINGS reports whether they were really built. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. The bindings hook sits outside the USE_SYSTEM_LIB branch: that branch controls whether librocrand is built here, and the bindings need it linked, not built. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides ROCRAND_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. Note that rocm_export_targets' INCLUDE argument is not a substitute for the OPTIONAL sibling include the config comment describes: it emits a bare, non-OPTIONAL include(), and emits it before the targets file, so a Fortran config reached that way would run before roc::rocrand exists. That hook belongs in rocm-cmake. Tests ----- 24 tests under CTest, off by default, replacing the FRUIT suite. Twenty-three are runtime tests, one per (generator, distribution) pair, that allocate and copy device memory around each rocRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_rocrand.F03, the exhaustive symbol test, uses only iso_c_binding and rocrand, so it is registered outside that guard, behind BUILD_FORTRAN_EXTENDED_TESTS. That distinction is load bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against librocrand. Runtime tests are labelled gpu and the symbol test symbols, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 26, 2026
…ted one JIRA ID : ROCM-31390 rocblas.F90 is generated from the rocBLAS public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocblas`, carrying the interfaces, the enum constants, the opaque handles and the rocblasCheck status helper. A consumer writes one `use rocblas` and links roc::rocblas_fortran. Implements RFC0014 (ROCm/TheRock#8122) for rocBLAS, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written binding --------------------------------- library/include/rocblas_module.f90 is removed, along with the rocm_install() rule that shipped it into include/rocblas. It defined TWO modules, rocblas and rocblas_enums; the generated binding defines only rocblas, with the enum constants folded in. `use rocblas` is unchanged, but `use rocblas_enums` becomes `use rocblas`, which is applied here to the clients' shims and samples. Consumers get a compiled archive and .mod rather than a .f90 source to build themselves. clients no longer compiles its own rocblas_fortran object library from that source; rocblas_fortran_client links the target ../fortran exports. Both carried the same name, so this also removes a latent duplicate-target clash. next-cmake, which built its own rocblas-fortran-module from the same file, now builds the generated source instead. The add_subdirectory(fortran) hook moves out of the SKIP_LIBRARY guard: that guard decides whether librocblas is built here, and the bindings need it linked, not built. With clients now consuming the target rather than building their own, inheriting the skip would leave BUILD_FORTRAN_CLIENTS with no rocblas_fortran. Linking against an older rocBLAS -------------------------------- The archive is built with -ffunction-sections -fdata-sections and exports --gc-sections to its consumers. The module is generated from THIS tree's headers, so it wraps API no released ROCm has yet -- the six rocblas_*gemm_grouped_batched entry points today. A static archive links at object granularity, so pulling in one wrapper pulls in every undefined C symbol the object references, and a consumer who never touches the new API would still fail to link. With section GC the unreferenced wrappers are discarded. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCBLAS_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK. ROCBLAS_HAVE_FORTRAN_BINDINGS reports whether they were built. The compiler probe is read from ROCM_HAVE_FORTRAN, with ROCM_LIBS_HAVE_FORTRAN honoured second as the spelling this repository's root publishes today. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>, the directory derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name, which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler overrides ROCBLAS_FORTRAN_COMPILER_DIR; the config accepts the derived name or that name followed by a separator and anything, compared by length and substring rather than by regex. This uses the shared layout: the real config is co-installed in lib/cmake/rocblas beside the C package, with a forwarder in lib/cmake/rocblas-fortran. rocblas-config.cmake carries no Fortran include, so the recursion hazard that keeps rocRAND and hipRAND in a directory of their own does not apply here. The config-version file is installed into BOTH package directories. CMake looks for it next to the <pkg>-config.cmake it actually resolved, and find_package(rocblas-fortran 5.8) resolves the forwarder, so a version file only beside the real config is never consulted and the call fails even though the version matches. Its version is parsed from this tree's VERSION_STRING rather than from rocblas_VERSION, which is set by the find_package(rocblas) this directory does for its link interface and would report whatever rocBLAS happens to be installed. Tests ----- 81 tests under CTest, off by default: 80 runtime tests carried over from hipFORT, which allocate and copy device memory and so need the HIP Fortran binding at compile time, plus test_rocblas.F03, the exhaustive symbol test, which uses only iso_c_binding and rocblas and is registered outside that guard behind BUILD_FORTRAN_EXTENDED_TESTS.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 26, 2026
JIRA ID : ROCM-31390 rocrand.F90 is generated from the rocRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocrand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the rocrandCheck status helper. A consumer writes one `use rocrand` and links roc::rocrand_fortran. Implements RFC0014 (ROCm/TheRock#8122) for rocRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written wrapper --------------------------------- library/src/fortran (rocrand_m.f90, hip_m.f90), its config template, and the FRUIT-based suite under test/fortran go with it, along with BUILD_FORTRAN_WRAPPER and its references in the top-level CMakeLists, library/CMakeLists.txt, test/CMakeLists.txt, cmake/Summary.cmake, cmake/Dependencies.cmake and docs/install/build.rst. That API was deprecated in favour of hipfort in rocRAND 4.0.0 / ROCm 7.0 and has never been shipped enabled: ROCm builds with BUILD_FORTRAN_WRAPPER=OFF, so in an installed /opt/rocm rocrand_FORTRAN_FOUND is NOTFOUND, rocrand_FORTRAN_SRC_DIRS is never set, and rocrand/src/fortran does not exist. No consumer of a ROCm package can therefore be using it; only a source build that passed the flag. Removing it also frees two names the generated bindings want. The target rocrand_fortran was defined by both, which is a hard CMake error. More importantly lib/cmake/rocrand/rocrand-fortran-config.cmake belonged to the wrapper, and rocrand-config.cmake include()s that name unconditionally, so the new package could not have been co-installed beside the C one while the wrapper stood. With the wrapper gone, rocRAND uses the same layout as the rest of the series: the real config in lib/cmake/rocrand, a forwarder in lib/cmake/rocrand-fortran, and rocrand_FORTRAN_FOUND back to its ordinary meaning. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCRAND_HAVE_FORTRAN_BINDINGS reports whether they were really built. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. The bindings hook sits outside the USE_SYSTEM_LIB branch: that branch controls whether librocrand is built here, and the bindings need it linked, not built. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides ROCRAND_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. Note that rocm_export_targets' INCLUDE argument is not a substitute for the OPTIONAL sibling include the config comment describes: it emits a bare, non-OPTIONAL include(), and emits it before the targets file, so a Fortran config reached that way would run before roc::rocrand exists. That hook belongs in rocm-cmake. Tests ----- 24 tests under CTest, off by default, replacing the FRUIT suite. Twenty-three are runtime tests, one per (generator, distribution) pair, that allocate and copy device memory around each rocRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_rocrand.F03, the exhaustive symbol test, uses only iso_c_binding and rocrand, so it is registered outside that guard, behind BUILD_FORTRAN_EXTENDED_TESTS. That distinction is load bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against librocrand. Runtime tests are labelled gpu and the symbol test symbols, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 27, 2026
…rated one JIRA ID : ROCM-31390 hipsparse.F90 is generated from the hipSPARSE public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hipsparse`, carrying the interfaces, the enum constants, the opaque handles and the hipsparseCheck status helper. A consumer writes one `use hipsparse` and links roc::hipsparse_fortran. Implements RFC0014 (ROCm/TheRock#8122) for hipSPARSE, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written module -------------------------------- library/src/hipsparse.f90 and hipsparse_enums.f90 are removed, along with the hipsparse_fortran OBJECT target in library/CMakeLists.txt that compiled them. That target carried the SAME NAME as the one this directory creates, so with -DHIPSPARSE_ENABLE_CLIENT=ON the two collided outright: CMake Error at fortran/CMakeLists.txt (add_library): add_library cannot create target "hipsparse_fortran" because another target with the same name already exists CI never saw it because HIPSPARSE_ENABLE_FORTRAN is declared inside if(HIPSPARSE_ENABLE_CLIENT), which defaults OFF. The Fortran samples now link roc::hipsparse_fortran, which carries both the .mod directory and the archive, and HIPSPARSE_ENABLE_FORTRAN is turned off with a message when the bindings were not built, so -DHIPSPARSE_ENABLE_CLIENT=ON still works without a Fortran compiler. Host and device pointer mode ---------------------------- The generated binding follows hipFORT and binds a `const T*` scalar as a by-reference `real(c_double) :: alpha`. The removed module bound the same argument as `type(c_ptr), value`, so every sample passes `c_loc(alpha)`. Both are ABI-correct, but only the second can express HIPSPARSE_POINTER_MODE_DEVICE, where the library reads alpha from device memory: a type(c_ptr) cannot be passed where a real is expected. example_fortran_spmv.f90 does exactly that, passing a hipMalloc'd d_alpha to hipsparseDbsrmv. So 25 generics gained a second specific taking those scalars as type(c_ptr),value and forwarding through c_f_pointer, which only records the address and never dereferences it on the host. Six zeroPivot routines were plain functions rather than generics and became generics to carry both; their own documentation states that `position` can be in host OR device memory. No sample and no test was modified: all 32 samples and all 50 tests build and pass against the binding as committed. This is a local fix in a GENERATED file, kept narrow deliberately. The ~700 other scalar arguments in hipSPARSE, and the same arguments in rocBLAS, hipBLAS, rocSPARSE and rocSOLVER, still cannot express device pointer mode. The durable fix belongs in the generator and will have to re-emit these variants. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPSPARSE_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape). HIPSPARSE_HAVE_FORTRAN_BINDINGS reports whether the bindings were really built. The compiler probe reads ROCM_HAVE_FORTRAN, with ROCM_LIBS_HAVE_FORTRAN honoured second. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>, the directory derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name. The config picks the consumer's own compiler when its .mod is installed, so a prefix holding several compilers' artifacts resolves without an override, and repoints the imported target accordingly. The real config is co-installed in lib/cmake/hipsparse beside the C package, with a forwarder in lib/cmake/hipsparse-fortran. The config-version file goes into both directories, because CMake looks for it next to the config it actually resolved and the versioned spelling resolves the forwarder. Its version is parsed from this tree's project(hipsparse VERSION ...) rather than from hipsparse_VERSION, which the find_package(hipsparse) this directory does for its link interface would set to the installed version. The generated hipsparse.F90 installs to share/hipsparse/fortran, so a user on a compiler with no shipped .mod can rebuild the binding without cloning a monorepo to get one file. Tests ----- 50 tests under CTest, off by default: 49 runtime tests carried over from hipFORT, which allocate and copy device memory and so need the HIP Fortran binding at compile time, plus test_hipsparse.F03, the exhaustive symbol test, which uses only iso_c_binding and hipsparse and is registered outside that guard behind BUILD_FORTRAN_EXTENDED_TESTS.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 27, 2026
rocfft.F90 is generated from the rocFFT public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocfft`, carrying the interfaces, the enum constants, the opaque handles and the rocfftCheck status helper. A consumer writes one `use rocfft`. Implements RFC0014 (ROCm/TheRock#8122) for rocFFT, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: a Fortran binding declares bind(C) interfaces only, so it compiles against neither the rocFFT headers nor librocfft, and needs no GPU and no HIP compiler to build. librocfft is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCFFT_BUILD_FORTRAN_* so one library can be singled out in a monorepo build. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCFFT_HAVE_FORTRAN_BINDINGS reports whether they were really built, and the config package sets rocfft_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, which is the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, Flang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper, where a plain basename would not. The generated source is installed too, as share/rocfft/fortran/rocfft.F90, so that a user on a compiler ROCm ships no .mod for can rebuild the binding without cloning a monorepo to get one file, and cannot end up with source generated from a different ROCm than the librocfft they link. It goes under share/ rather than include/ deliberately: everything under include/fortran/ is partitioned by compiler and the config enumerates that directory to report which compilers are installed, so a compiler-independent source file there would be listed as though it were one. The config package lands in lib/cmake/rocfft beside the C package, and a forwarder in lib/cmake/rocfft-fortran makes find_package(rocfft-fortran) resolve to the same place. A version file is installed into BOTH directories, and it has to be: CMake looks for the version file next to the config it actually resolved, so find_package(rocfft-fortran 1.0) resolves the forwarder and would never see a version file kept only beside the real config. The number is parsed from this tree's projects/rocfft/CMakeLists.txt, never from rocfft_VERSION, which in a standalone build reports whatever rocFFT happens to be installed. rocFFT composes VERSION_STRING from ROCFFT_VERSION_MAJOR / _MINOR / _PATCH rather than spelling a literal, so the three components are read and recomposed; when that fails, no version file is installed and a STATUS message says so, because a file claiming the wrong number is worse than none. The recorded compiler directory is only a DEFAULT. A prefix can hold artifacts for several compilers at once, while the config package is written once and names whichever install ran last, so the config prefers the consumer's own compiler when its .mod is present under the prefix, falls back to the recorded directory otherwise, and fails naming what IS available. When the resolved directory differs from the recorded one it repoints INTERFACE_INCLUDE_DIRECTORIES and every IMPORTED_LOCATION_<CFG>, without which find_package would succeed while linking the wrong archive. The archive is compiled with -ffunction-sections -fdata-sections and exports --gc-sections to consumers. A static archive links at object granularity and this module is one object, so one wrapper otherwise pulls in every undefined C symbol the object references: the first rocFFT entry point added after a release would break the link for consumers who never call it. Both are guarded on the compilers known to accept the spelling. Tests ----- test/ carries 19 tests under CTest. Eighteen are runtime tests that allocate device memory, so they write `use hip` next to `use rocfft` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. test_rocfft.F03, the exhaustive symbol test, uses only iso_c_binding and rocfft, so it is registered outside that guard. That distinction is load-bearing: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only one that proves every bind(C) symbol resolves against librocfft. Runtime tests are labelled "gpu" and the symbol test "symbols", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with gfortran 13.3.0. Standalone configure is clean under -Wdev, the version resolves to 1.0.41 and the version file installs into both cmake directories. Against a stock /opt/rocm the symbol test builds, links and passes on its own. With the HIP Fortran binding available, 19 of 19 pass; one of those, field_brick_z, prints SKIPPED and exits 0 because it wants two GPUs, so the honest reading is 17 real GPU tests, 1 self-skip and the symbol test. The documented consumer path was exercised end to end: install, find_package(rocfft-fortran 1.0), link roc::rocfft_fortran, run on the GPU. The per-compiler fallback was exercised by hand too: with the recorded directory pointing at a compiler whose .mod is not installed, the consumer's own compiler is picked and the imported target repointed at it, and with no usable directory at all find_package fails naming what is installed.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 27, 2026
hipfft.F90 and hipfftw.F90 are generated from the public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. Each is a single self-contained module, `hipfft` and `hipfftw`, carrying the interfaces, the enum constants, the opaque handles and the status helper. A consumer writes one `use hipfft`. Implements RFC0014 (ROCm/TheRock#8122) for hipFFT, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Two bindings in one directory, because hipFFTW is built by the hipFFT project rather than one of its own. They are separate modules, separate targets and separate config packages, but they live next to the headers they bind rather than in a directory of their own. The bindings declare bind(C) interfaces only, so they compile against neither the hipFFT headers nor libhipfft, and need no GPU and no HIP compiler to build. The C libraries are link-time dependencies of a final executable and are carried as each target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPFFT_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. The config packages set hipfft_FORTRAN_FOUND and hipfftw_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so each .mod and archive installs under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper, where a plain basename would not. Both config packages land in lib/cmake/hipfft beside the C package, and forwarders in lib/cmake/hipfft-fortran and lib/cmake/hipfftw-fortran make find_package(hipfft-fortran) and find_package(hipfftw-fortran) resolve to the same place. Each package gets a config-version file, stamped with hipFFT's version (hipFFTW has none of its own) parsed from the HIPFFT_VERSION_* components in this tree rather than from hipfft_VERSION, which reports whatever hipFFT is INSTALLED. Both files install into BOTH of their package directories, because CMake looks for the version file next to the config it actually resolved and the versioned spelling resolves the forwarder. When the version cannot be read, no version file is installed and a STATUS message says so: a file claiming the wrong number is worse than none. The recorded compiler directory is only a DEFAULT. A prefix can hold artifacts for several compilers while the config is written once, so each config prefers the consumer's own compiler when its .mod is installed under the prefix -- hipfft.mod for one package, hipfftw.mod for the other, since either half is switchable on its own -- falls back to the recorded directory, and otherwise names what IS available. When the resolved directory differs from the recorded one, INTERFACE_INCLUDE_DIRECTORIES and every IMPORTED_LOCATION_<CFG> are repointed, or find_package would succeed while linking the wrong archive. Both generated sources also install to share/hipfft/fortran, so that a user on a compiler ROCm ships no .mod for can rebuild without cloning a monorepo. Under share/ and not include/, because everything under include/fortran/ is partitioned by compiler and the configs glob that directory to report which compilers are present. Both archives are built with -ffunction-sections -fdata-sections and export --gc-sections to consumers, guarded on the compilers that accept the spelling. A static archive links at object granularity and each of these is one object, so without section GC one wrapper pulls in every undefined C symbol the whole module references, and a consumer fails to link over API their installed .so lacks. Tests ----- test/ carries 21 tests under CTest. Nineteen are runtime tests that allocate device memory, so they write `use hip` next to their own `use`, which makes the HIP Fortran binding a compile-time dependency; they are skipped with a named message when it is absent. The two exhaustive symbol tests use only iso_c_binding and the module under test, so they are registered outside that guard. That distinction matters: ROCm does not currently ship a HIP Fortran binding, so guarding the whole directory would mean zero tests against a stock /opt/rocm, including the only ones that prove every bind(C) symbol resolves against the installed libraries. Runtime tests are labelled "gpu" and the symbol tests "symbols", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with BOTH compilers, gfortran 13.3.0 and amdflang 23.0.0. Against a stock /opt/rocm the two symbol tests build, link and pass on their own; with the HIP Fortran binding available, 21 of 21 pass. The documented consumer path was exercised end to end with amdflang: install, find_package on both packages, link hip::hipfft_fortran and hip::hipfftw_fortran in one program, run on the GPU. The compiler-mismatch diagnostic was exercised for real by installing with amdflang and consuming with gfortran, which is what confirms the CMAKE_Fortran_COMPILER_ID mapping handles LLVMFlang and that the message renders as prose rather than as a semicolon-separated list. The per-compiler selection was verified the same way: both bindings installed into one prefix twice, with gfortran and then amdflang, so that the configs record amdflang while the gfortran artifacts are still present. A gfortran consumer then still resolves both packages, compiles against include/fortran/gfortran and links lib/fortran/gfortran, which is the repointing working. Removing only gfortran's hipfftw.mod makes hipfftw-fortran fail with the named message while hipfft-fortran still resolves, which is the per-module glob working. find_package(hipfft-fortran 1.0) and find_package(hipfftw-fortran 1.0) both resolve through their forwarders and report 1.0.27; 2.0 is refused.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 28, 2026
…rated one JIRA ID : ROCM-31390 hipsparse.F90 is generated from the hipSPARSE public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hipsparse`, carrying the interfaces, the enum constants, the opaque handles and the hipsparseCheck status helper. A consumer writes one `use hipsparse` and links roc::hipsparse_fortran. Implements RFC0014 (ROCm/TheRock#8122) for hipSPARSE, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written module -------------------------------- library/src/hipsparse.f90 and hipsparse_enums.f90 are removed, along with the hipsparse_fortran OBJECT target in library/CMakeLists.txt that compiled them. That target carried the SAME NAME as the one this directory creates, so with -DHIPSPARSE_ENABLE_CLIENT=ON the two collided outright: CMake Error at fortran/CMakeLists.txt (add_library): add_library cannot create target "hipsparse_fortran" because another target with the same name already exists CI never saw it because HIPSPARSE_ENABLE_FORTRAN is declared inside if(HIPSPARSE_ENABLE_CLIENT), which defaults OFF. The Fortran samples now link roc::hipsparse_fortran, which carries both the .mod directory and the archive, and HIPSPARSE_ENABLE_FORTRAN is turned off with a message when the bindings were not built, so -DHIPSPARSE_ENABLE_CLIENT=ON still works without a Fortran compiler. Host and device pointer mode ---------------------------- The generated binding follows hipFORT and binds a `const T*` scalar as a by-reference `real(c_double) :: alpha`. The removed module bound the same argument as `type(c_ptr), value`, so every sample passes `c_loc(alpha)`. Both are ABI-correct, but only the second can express HIPSPARSE_POINTER_MODE_DEVICE, where the library reads alpha from device memory: a type(c_ptr) cannot be passed where a real is expected. example_fortran_spmv.f90 does exactly that, passing a hipMalloc'd d_alpha to hipsparseDbsrmv. So 25 generics gained a second specific taking those scalars as type(c_ptr),value and forwarding through c_f_pointer, which only records the address and never dereferences it on the host. Six zeroPivot routines were plain functions rather than generics and became generics to carry both; their own documentation states that `position` can be in host OR device memory. No sample and no test was modified: all 32 samples and all 49 tests build and pass against the binding as committed. This is a local fix in a GENERATED file, kept narrow deliberately. The ~700 other scalar arguments in hipSPARSE, and the same arguments in rocBLAS, hipBLAS, rocSPARSE and rocSOLVER, still cannot express device pointer mode. The durable fix belongs in the generator and will have to re-emit these variants. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPSPARSE_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape). HIPSPARSE_HAVE_FORTRAN_BINDINGS reports whether the bindings were really built. The compiler probe reads ROCM_HAVE_FORTRAN, with ROCM_LIBS_HAVE_FORTRAN honoured second. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>, the directory derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name. The config picks the consumer's own compiler when its .mod is installed, so a prefix holding several compilers' artifacts resolves without an override, and repoints the imported target accordingly. The real config is co-installed in lib/cmake/hipsparse beside the C package, with a forwarder in lib/cmake/hipsparse-fortran. The config-version file goes into both directories, because CMake looks for it next to the config it actually resolved and the versioned spelling resolves the forwarder. Its version is parsed from this tree's project(hipsparse VERSION ...) rather than from hipsparse_VERSION, which the find_package(hipsparse) this directory does for its link interface would set to the installed version. The generated hipsparse.F90 installs to share/hipsparse/fortran, so a user on a compiler with no shipped .mod can rebuild the binding without cloning a monorepo to get one file. Tests ----- 49 tests under CTest, off by default: the runtime tests carried over from hipFORT, which allocate and copy device memory and so need the HIP Fortran binding at compile time, and are skipped with a named message when it is absent. They are labelled gpu, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 28, 2026
…ted one JIRA ID : ROCM-31390 hipblas.F90 is generated from the hipBLAS public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hipblas`, carrying the interfaces, the enum constants, the opaque handles and the hipblasCheck status helper. A consumer writes one `use hipblas` and links roc::hipblas_fortran. Implements RFC0014 (ROCm/TheRock#8122) for hipBLAS, following the shape already reviewed for HIP in ROCm/rocm-systems#11923, and mirroring rocBLAS. Removing the hand-written binding --------------------------------- library/src/hipblas_module.f90 is removed, along with the rocm_install() rule that shipped it into include/hipblas. It defined TWO modules, hipblas and hipblas_enums; the generated binding defines only hipblas, with the hipBLAS enum constants folded in. `use hipblas` is unchanged, `use hipblas_enums` becomes `use hipblas`, applied here across 1197 sites in the clients. clients no longer compiles its own hipblas_fortran object library from that source; hipblas_fortran_client links the target ../fortran exports. Both carried the same name, so this also removes a latent duplicate-target clash. The BUILD_WITH_SOLVER split is preserved. Because hipBLAS's consumers absorb $<TARGET_OBJECTS:hipblas_fortran_client> rather than linking it, and that carries neither the archive nor the .mod include directory, the Fortran samples and rocblas-bench now link hipblas_fortran_client explicitly. The hipDataType enumerators, and why a stub ships temporarily ------------------------------------------------------------- hipblas_enums also re-exported HIP's hipDataType enumerators. The generated module does not: a hipDataType belongs to HIP, and the generated interfaces type those arguments as plain integer(c_int). That is correct, but it leaves the client shims -- which declare their datatype arguments as integer(kind(HIP_R_16F)) -- with no source for the name. 57 scopes across clients/include/hipblas_fortran_blas{,_64}.f90 are affected, and they now say `use hip`. ROCm ships no HIP Fortran binding yet, so fortran/hip_datatypes_stub.F90 provides one, carrying only the sixteen enumerators those scopes reference, with values copied verbatim from the HIP binding. It is compiled into hipblas_fortran_client and is NOT installed, exported or packaged, so no second hip.mod can reach an installed prefix and collide with the real binding. It is meant to be deleted. When ROCm/rocm-systems#11923 lands: drop the stub from the source list and from fortran/, then find_package(hip-fortran) and link hip::hip_fortran. The `use hip` lines do not change -- they start resolving to the real module, which declares the same enumerators with the same values, so the swap is observably a no-op. Note that a hipBLAS USER calling hipblasGemmEx needs those values too, and the stub does not help them since it is not installed. Until the HIP binding ships they need `use hip` from a HIP binding of their own. hipSPARSE has the same gap. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable through HIPBLAS_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape). Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The shared layout is used: the real config in lib/cmake/hipblas beside the C package, a forwarder in lib/cmake/hipblas-fortran. The config-version file is installed into BOTH package directories, because CMake looks for it next to the <pkg>-config.cmake it actually resolved and find_package(hipblas-fortran 3.8) resolves the forwarder. Its version is parsed from this tree's VERSION_STRING rather than from hipblas_VERSION, which the find_package(hipblas) this directory does for its link interface would set to the installed version. Section GC (-ffunction-sections, --gc-sections) is carried over from rocBLAS. hipBLAS needs none of it today -- every symbol the module references is present in the installed libhipblas -- because this binding currently lags the headers rather than running ahead of them. It is kept so the next regeneration that picks up a new entry point does not reintroduce undefined references in downstream builds. Tests ----- 69 tests under CTest, off by default: 68 runtime tests from hipFORT plus test_hipblas.F03, the exhaustive symbol test, registered outside the hip::hip_fortran guard behind BUILD_FORTRAN_EXTENDED_TESTS.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 28, 2026
JIRA ID : ROCM-31390 hiprand.F90 is generated from the hipRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `hiprand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the hiprandCheck status helper. A consumer writes one `use hiprand` and links hip::hiprand_fortran. Implements RFC0014 (ROCm/TheRock#8122) for hipRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written wrapper --------------------------------- library/src/fortran (hiprand_m.f90, hip_m.f90), its config template, and the FRUIT-based suite under test/fortran go with it, along with BUILD_FORTRAN_WRAPPER and its references in the top-level CMakeLists, library/CMakeLists.txt, test/CMakeLists.txt, cmake/Summary.cmake, cmake/Dependencies.cmake, docs/install/build.rst and testing.md. That API was deprecated in favour of hipfort in hipRAND 3.0.0 / ROCm 7.0 and has never been shipped enabled: ROCm builds with BUILD_FORTRAN_WRAPPER=OFF, so in an installed /opt/rocm hiprand_FORTRAN_FOUND is NOTFOUND, hiprand_FORTRAN_SRC_DIRS is never set, and hiprand/src/fortran does not exist. No consumer of a ROCm package can therefore be using it; only a source build that passed the flag. Removing it frees the target name hiprand_fortran, which both defined and which is a hard CMake error. Why the config package still stands alone ----------------------------------------- It does NOT free lib/cmake/hiprand/hiprand-fortran-config.cmake, and that is the one place rocRAND and hipRAND diverge from the rest of the series. Removing the wrapper frees that name in this source tree, but not in prefixes that are already installed. Every ROCm shipped so far has a hiprand-config.cmake whose line 94 is a bare, unguarded include() of a sibling by that exact name. Installing this package's config there hands that include a file that calls find_dependency(hiprand), which re-enters hiprand-config.cmake, which includes the Fortran config again -- unbounded recursion until CMake gives up. That is precisely the documented standalone path: build the binding yourself and install it into an existing /opt/rocm, which is what anyone whose compiler is not the shipped amdflang has to do. So the package installs only into lib/cmake/hiprand-fortran, where find_package(hiprand-fortran) resolves it directly and no forwarder is needed. When rocm-cmake grows an OPTIONAL end-of-config hook and no supported ROCm still carries the old unguarded include, this can join the shared layout. A config-version file is installed alongside, so find_package(hiprand-fortran 3.4) resolves. Its version is parsed from this tree's own VERSION_STRING, not from hiprand_VERSION: that variable is set by the find_package(hiprand) this directory does for its link interface, so it would report whatever hipRAND happens to be installed rather than the headers the bindings were generated from. When the version cannot be determined, no file is written at all, because a version file claiming the wrong number is worse than none. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK. HIPRAND_HAVE_FORTRAN_BINDINGS reports whether they were built. BUILD_FORTRAN_BINDINGS is declared at the top level as well as in fortran/, because print_configuration_summary() runs before add_subdirectory(fortran) and would otherwise report an empty value. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>, the name derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name, which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler overrides HIPRAND_FORTRAN_COMPILER_DIR; the config accepts the derived name or that name followed by a separator and anything, compared by length and substring rather than by regex, since the derived name can be an arbitrary file name. Tests ----- 23 tests under CTest, off by default, replacing the FRUIT suite. One per (generator, distribution) pair, each allocating and copying device memory around its hipRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. They are labelled gpu, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 28, 2026
…ted one JIRA ID : ROCM-31390 rocblas.F90 is generated from the rocBLAS public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocblas`, carrying the interfaces, the enum constants, the opaque handles and the rocblasCheck status helper. A consumer writes one `use rocblas` and links roc::rocblas_fortran. Implements RFC0014 (ROCm/TheRock#8122) for rocBLAS, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written binding --------------------------------- library/include/rocblas_module.f90 is removed, along with the rocm_install() rule that shipped it into include/rocblas. It defined TWO modules, rocblas and rocblas_enums; the generated binding defines only rocblas, with the enum constants folded in. `use rocblas` is unchanged, but `use rocblas_enums` becomes `use rocblas`, which is applied here to the clients' shims and samples. Consumers get a compiled archive and .mod rather than a .f90 source to build themselves. clients no longer compiles its own rocblas_fortran object library from that source; rocblas_fortran_client links the target ../fortran exports. Both carried the same name, so this also removes a latent duplicate-target clash. next-cmake, which built its own rocblas-fortran-module from the same file, now builds the generated source instead. The add_subdirectory(fortran) hook moves out of the SKIP_LIBRARY guard: that guard decides whether librocblas is built here, and the bindings need it linked, not built. With clients now consuming the target rather than building their own, inheriting the skip would leave BUILD_FORTRAN_CLIENTS with no rocblas_fortran. Linking against an older rocBLAS -------------------------------- The archive is built with -ffunction-sections -fdata-sections and exports --gc-sections to its consumers. The module is generated from THIS tree's headers, so it wraps API no released ROCm has yet -- the six rocblas_*gemm_grouped_batched entry points today. A static archive links at object granularity, so pulling in one wrapper pulls in every undefined C symbol the object references, and a consumer who never touches the new API would still fail to link. With section GC the unreferenced wrappers are discarded. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCBLAS_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK. ROCBLAS_HAVE_FORTRAN_BINDINGS reports whether they were built. The compiler probe is read from ROCM_HAVE_FORTRAN, with ROCM_LIBS_HAVE_FORTRAN honoured second as the spelling this repository's root publishes today. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>, the directory derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name, which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler overrides ROCBLAS_FORTRAN_COMPILER_DIR; the config accepts the derived name or that name followed by a separator and anything, compared by length and substring rather than by regex. This uses the shared layout: the real config is co-installed in lib/cmake/rocblas beside the C package, with a forwarder in lib/cmake/rocblas-fortran. rocblas-config.cmake carries no Fortran include, so the recursion hazard that keeps rocRAND and hipRAND in a directory of their own does not apply here. The config-version file is installed into BOTH package directories. CMake looks for it next to the <pkg>-config.cmake it actually resolved, and find_package(rocblas-fortran 5.8) resolves the forwarder, so a version file only beside the real config is never consulted and the call fails even though the version matches. Its version is parsed from this tree's VERSION_STRING rather than from rocblas_VERSION, which is set by the find_package(rocblas) this directory does for its link interface and would report whatever rocBLAS happens to be installed. Tests ----- 80 tests under CTest, off by default: the runtime tests carried over from hipFORT, which allocate and copy device memory and so need the HIP Fortran binding at compile time, and are skipped with a named message when it is absent. They are labelled gpu, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 28, 2026
JIRA ID : ROCM-31390 rocrand.F90 is generated from the rocRAND public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocrand`, carrying the interfaces, the enum constants, the derived types, the opaque handles and the rocrandCheck status helper. A consumer writes one `use rocrand` and links roc::rocrand_fortran. Implements RFC0014 (ROCm/TheRock#8122) for rocRAND, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written wrapper --------------------------------- library/src/fortran (rocrand_m.f90, hip_m.f90), its config template, and the FRUIT-based suite under test/fortran go with it, along with BUILD_FORTRAN_WRAPPER and its references in the top-level CMakeLists, library/CMakeLists.txt, test/CMakeLists.txt, cmake/Summary.cmake, cmake/Dependencies.cmake and docs/install/build.rst. That API was deprecated in favour of hipfort in rocRAND 4.0.0 / ROCm 7.0 and has never been shipped enabled: ROCm builds with BUILD_FORTRAN_WRAPPER=OFF, so in an installed /opt/rocm rocrand_FORTRAN_FOUND is NOTFOUND, rocrand_FORTRAN_SRC_DIRS is never set, and rocrand/src/fortran does not exist. No consumer of a ROCm package can therefore be using it; only a source build that passed the flag. Removing it also frees two names the generated bindings want. The target rocrand_fortran was defined by both, which is a hard CMake error. More importantly lib/cmake/rocrand/rocrand-fortran-config.cmake belonged to the wrapper, and rocrand-config.cmake include()s that name unconditionally, so the new package could not have been co-installed beside the C one while the wrapper stood. With the wrapper gone, rocRAND uses the same layout as the rest of the series: the real config in lib/cmake/rocrand, a forwarder in lib/cmake/rocrand-fortran, and rocrand_FORTRAN_FOUND back to its ordinary meaning. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCRAND_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCRAND_HAVE_FORTRAN_BINDINGS reports whether they were really built. The compiler probe is read from ROCM_HAVE_FORTRAN, the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. The bindings hook sits outside the USE_SYSTEM_LIB branch: that branch controls whether librocrand is built here, and the bindings need it linked, not built. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, LLVMFlang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler side by side overrides ROCRAND_FORTRAN_COMPILER_DIR with a suffixed name, so the config package accepts the recorded directory when it is the derived name OR that name followed by a separator and anything. The comparison is done by length and substring rather than by regex: the derived name comes from the compiler's basename on the fallback branch, so it is an arbitrary file name, and interpolating it into a regex would let a compiler called flang(2) either mismatch silently or abort CMake outright. Note that rocm_export_targets' INCLUDE argument is not a substitute for the OPTIONAL sibling include the config comment describes: it emits a bare, non-OPTIONAL include(), and emits it before the targets file, so a Fortran config reached that way would run before roc::rocrand exists. That hook belongs in rocm-cmake. Tests ----- 23 tests under CTest, off by default, replacing the FRUIT suite. One per (generator, distribution) pair, each allocating and copying device memory around its rocRAND call, so they write `use hip` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. They are labelled gpu, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 28, 2026
…rated one JIRA ID : ROCM-31390 rocsparse.F90 is generated from the rocSPARSE public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocsparse`, carrying the interfaces, the enum constants, the opaque handles and the rocsparseCheck status helper. A consumer writes one `use rocsparse` and links roc::rocsparse_fortran. Implements RFC0014 (ROCm/TheRock#8122) for rocSPARSE, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written binding --------------------------------- library/src/rocsparse.f90 and library/src/rocsparse_enums.f90 are removed, along with the rocm_install(FILES ...) rule that shipped them into include/rocsparse. Unlike rocRAND's wrapper, this one WAS shipped and built by default, so the removal is user visible: the module keeps the name `rocsparse`, but the separate `rocsparse_enums` module is gone -- its constants are part of `rocsparse` -- and consumers get a compiled archive and .mod rather than .f90 sources to build themselves. clients no longer compiles its own rocsparse_fortran object library from those sources; it consumes the one ../fortran exports. Both carried the same target name, so this also removes a latent duplicate-target clash. All fourteen existing Fortran samples compile unmodified against the generated module. The add_subdirectory(fortran) hook moves out of the BUILD_CLIENTS_ONLY branch. That is a bug fix, not tidying: clients now require the rocsparse_fortran target and BUILD_FORTRAN_CLIENTS defaults to ON, so -DBUILD_CLIENTS_ONLY=ON skipped the directory and then stopped in clients with "the rocsparse_fortran target is missing". Linking against an older rocSPARSE ---------------------------------- The archive is built with -ffunction-sections -fdata-sections and exports --gc-sections to its consumers. This is not a size optimisation: the module is generated from THIS tree's headers, so it wraps API no released ROCm has yet (rocsparse_dnvec_descr_create_scalar, rocsparse_ell_set_strided_batch, rocsparse_spmat_scale today). A static archive links at object granularity, so pulling in one wrapper pulls in every undefined C symbol the object references. Without section GC a consumer who never touches the new API still fails to link, with 25 undefined references to functions they have never heard of; with it, the unreferenced wrappers are discarded and the link succeeds. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCSPARSE_BUILD_FORTRAN_*. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK. ROCSPARSE_HAVE_FORTRAN_BINDINGS reports whether they were built. The compiler probe is read from ROCM_HAVE_FORTRAN, with ROCM_LIBS_HAVE_FORTRAN honoured second as the spelling this repository's root publishes today. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>, the directory derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name, which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper. A site installing two versions of one compiler overrides ROCSPARSE_FORTRAN_COMPILER_DIR; the config accepts the derived name or that name followed by a separator and anything, compared by length and substring rather than by regex, since the derived name can be an arbitrary file name. This uses the SHARED layout: the real config is co-installed in lib/cmake/rocsparse beside the C package, with a forwarder in lib/cmake/rocsparse-fortran. rocRAND and hipRAND cannot do this because their shipped <lib>-config.cmake carries a bare unguarded include() of a sibling <lib>-fortran-config.cmake and a file there would recurse; rocsparse-config.cmake has no such include, checked against an installed ROCm. A config-version file is installed alongside, its version parsed from this tree's VERSION_STRING rather than from rocsparse_VERSION -- that variable is set by the find_package(rocsparse) this directory does for its link interface, so it would report whatever rocSPARSE happens to be installed. Tests ----- 58 tests under CTest, off by default: 57 runtime tests carried over from hipFORT, which allocate and copy device memory and so need the HIP Fortran binding at compile time, plus test_rocsparse.F03, the exhaustive symbol test, which uses only iso_c_binding and rocsparse and is registered outside that guard behind BUILD_FORTRAN_EXTENDED_TESTS. The csrgeam and csrgemm tests, all four precisions of each, are listed but commented out because they segfault, with the analysis recorded next to them. The cause is in the tests: both families select what they compute from whether alpha and beta are NULL POINTERS rather than from their values, and these tests pass beta = 0.0_c_double, a valid pointer, while passing c_null_ptr for descr_D and every D array, so rocSPARSE looks for a D term that is not there. The binding can express the NULL -- it carries a _dptr specific taking type(c_ptr),value :: alpha,beta -- so fixing them is a follow-up, not a change to the binding. Runtime tests are labelled gpu and the symbol test symbols, so ctest -LE gpu stays meaningful on a machine without one.
amontoison
added a commit
to amontoison/rocm-libraries
that referenced
this pull request
Sep 28, 2026
rocfft.F90 is generated from the rocFFT public headers by the rocm-fortran generator and committed next to them, so that a header change and its binding travel in the same pull request. It is a single self-contained module, `rocfft`, carrying the interfaces, the enum constants, the opaque handles and the rocfftCheck status helper. A consumer writes one `use rocfft`. Implements RFC0014 (ROCm/TheRock#8122) for rocFFT, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. The directory is self-contained: a Fortran binding declares bind(C) interfaces only, so it compiles against neither the rocFFT headers nor librocfft, and needs no GPU and no HIP compiler to build. librocfft is a link-time dependency of a final executable and is carried as the target's link interface. The subdirectory guards itself, returning early when BUILD_FORTRAN_BINDINGS is OFF or no Fortran compiler is present, so a C-only site is unaffected. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCFFT_BUILD_FORTRAN_* so one library can be singled out in a monorepo build. FORTRAN_ARRAY_INTERFACES is a tri-state (none / assumed-shape / assumed-rank, default assumed-shape) replacing the two booleans USE_FPOINTER_INTERFACES and ASSUMED_RANK: the two upper tiers cannot legally coexist in one generic, because an assumed-rank dummy is not distinguishable by rank from the per-rank specifics. ROCFFT_HAVE_FORTRAN_BINDINGS reports whether they were really built, and the config package sets rocfft_FORTRAN_FOUND. The compiler probe is read from ROCM_HAVE_FORTRAN, which is the name to settle on across both monorepos. This repository's root publishes ROCM_LIBS_HAVE_FORTRAN today, so that spelling is honoured second, never over the new name. It is a bridge with an end: when the root is switched over, that branch is dead code and goes. Install layout -------------- A .mod is not portable across compilers, so the .mod and the archive install under include/fortran/<compiler> and lib/fortran/<compiler>. The directory is derived from CMAKE_Fortran_COMPILER_ID and mapped back to the executable name (GNU to gfortran, Flang to amdflang, Cray to ftn), which survives an MPI wrapper, a versioned binary, an absolute path and the Cray wrapper, where a plain basename would not. The generated source is installed too, as share/rocfft/fortran/rocfft.F90, so that a user on a compiler ROCm ships no .mod for can rebuild the binding without cloning a monorepo to get one file, and cannot end up with source generated from a different ROCm than the librocfft they link. It goes under share/ rather than include/ deliberately: everything under include/fortran/ is partitioned by compiler and the config enumerates that directory to report which compilers are installed, so a compiler-independent source file there would be listed as though it were one. The config package lands in lib/cmake/rocfft beside the C package, and a forwarder in lib/cmake/rocfft-fortran makes find_package(rocfft-fortran) resolve to the same place. A version file is installed into BOTH directories, and it has to be: CMake looks for the version file next to the config it actually resolved, so find_package(rocfft-fortran 1.0) resolves the forwarder and would never see a version file kept only beside the real config. The number is parsed from this tree's projects/rocfft/CMakeLists.txt, never from rocfft_VERSION, which in a standalone build reports whatever rocFFT happens to be installed. rocFFT composes VERSION_STRING from ROCFFT_VERSION_MAJOR / _MINOR / _PATCH rather than spelling a literal, so the three components are read and recomposed; when that fails, no version file is installed and a STATUS message says so, because a file claiming the wrong number is worse than none. The recorded compiler directory is only a DEFAULT. A prefix can hold artifacts for several compilers at once, while the config package is written once and names whichever install ran last, so the config prefers the consumer's own compiler when its .mod is present under the prefix, falls back to the recorded directory otherwise, and fails naming what IS available. When the resolved directory differs from the recorded one it repoints INTERFACE_INCLUDE_DIRECTORIES and every IMPORTED_LOCATION_<CFG>, without which find_package would succeed while linking the wrong archive. The archive is compiled with -ffunction-sections -fdata-sections and exports --gc-sections to consumers. A static archive links at object granularity and this module is one object, so one wrapper otherwise pulls in every undefined C symbol the object references: the first rocFFT entry point added after a release would break the link for consumers who never call it. Both are guarded on the compilers known to accept the spelling. Tests ----- test/ carries 18 tests under CTest. All are runtime tests that allocate device memory, so they write `use hip` next to `use rocfft` and need the HIP Fortran binding at compile time; they are skipped with a named message when it is absent. They are labelled "gpu", so ctest -LE gpu stays meaningful on a machine without one. Verified against ROCm 10.0 on gfx1101 with gfortran 13.3.0. Standalone configure is clean under -Wdev, the version resolves to 1.0.41 and the version file installs into both cmake directories. With the HIP Fortran binding available, 18 of 18 pass; one of those, field_brick_z, prints SKIPPED and exits 0 because it wants two GPUs, so the honest reading is 17 real GPU tests and 1 self-skip. The documented consumer path was exercised end to end: install, find_package(rocfft-fortran 1.0), link roc::rocfft_fortran, run on the GPU. The per-compiler fallback was exercised by hand too: with the recorded directory pointing at a compiler whose .mod is not installed, the consumer's own compiler is picked and the imported target repointed at it, and with no usable directory at all find_package fails naming what is installed.
saadrahim
reviewed
Oct 13, 2026
…cm-libraries hipfort lives in a separate repository and its interfaces are partially hand-written, so its coverage is only ever as current as the last manual update. This RFC co-locates generated bindings with the C headers they mirror: the HIP runtime bindings in rocm-systems, each math library's bindings in rocm-libraries, each under a dedicated fortran/ directory, kept in sync by a CI gate that suggests the regenerated diff on the PR that changes a header. It also fixes the packaged deliverable (per-library .mod, archive, and CMake target under the C library's own namespace), the module naming (no hipfort_ prefix, one module per library), the Fortran standard tiers, and the two-track transition from today's hipfort.
A user on a compiler other than the one ROCm ships bindings for builds the binding themselves, and today that means cloning a monorepo to get the source. Installing it alongside the binding removes that step, and removes a failure mode with it: source fetched separately can come from a different ROCm than the installed .so, which surfaces as an undefined symbol at link time or as an interface that silently differs from the one the caller meant. Installed source matches the installed library by construction. It goes under share/<lib>/fortran/, not include/. The .mod is compiler-specific and the .F90 is not, and everything under include/fortran/ is partitioned by compiler. A source file placed there is a level error with a concrete symptom: a config that enumerates include/fortran/* to report the installed compilers lists the .F90 as though it were one, and invites the user to select it. share/ also leaves room if the Fortran side ever ships more than the module, and keeps a Fortran source out of the development-headers namespace that tooling walks. This breaks with where the hand-written modules lived (include/rocsparse/rocsparse.f90, include/hipblas/hipblas_module.f90). Those were headers by convention that a user compiled into their own build; the generated module is a source artifact of the library, and the filenames change in the move anyway, so there is no drop-in path to preserve.
Renumbered from RFC0014, which main now uses for the code coverage RFC;
0015 to 0018 are claimed by open RFC pull requests.
- roctx is no longer deferred: it ships with rocprofiler-sdk as
roc::roctx_fortran (rocm-systems#12700)
- discovery goes through the <lib>-fortran package; find_package(<lib>)
alone needs the rocm-cmake OPTIONAL hook, now in the backlog
- BUILD_FORTRAN_BINDINGS defaults to ${UNIX}; document the per-library
overrides, FORTRAN_ARRAY_INTERFACES (replacing USE_ASSUMED_RANK),
BUILD_FORTRAN_CLIENTS, the standalone fortran/ build, and the
per-compiler directory and its override
- the shared CMake helper is not there yet: say so, and move it to the
backlog with the ROCM_HAVE_FORTRAN / ROCM_LIBS_HAVE_FORTRAN split
- correct which hand-written modules were ever installed (three, not four)
- the hip* libraries default the bindings off on their CUDA backend
- hipfort is maintained beside the packaged bindings through 10.x and removed at 11.0; a binding holds for a major ROCm series - add the population that builds one code on several ROCm versions, some older than 10.2 - list the call-site changes for users of a library's own module, including handle creation by reference, which still compiles - link the migration guides (ROCm/hipfort#548) and list the 12 implementation pull requests
- set CMAKE_Fortran_COMPILER to the amdflang TheRock builds in the generated subproject toolchain, so every binding (and rocSOLVER against rocBLAS) uses the compiler that ships - install share/<lib>/fortran in the dev component; drop hipSOLVER's libhipsolver_fortran.so and EXPORT_FORTRAN_BINDINGS - tests, dependency order and the flang runtime need nothing new
As asked in review: if the need for an F77-callable path arises, it is prioritized separately, in its own RFC.
- add a summary of the decisions at the top - P2: each library builds its own binding and TheRock packages them; drop the separate job that collected every fortran/ directory - the CI hook is not implemented yet: it needs the generator repository to be public, which this RFC now settles - add the size of the generated files as an open question, as raised in review - drop fortran/examples/, which no project has, and describe the tests as each library's fortran/test/ rather than the hipfort suite
Co-authored-by: Saad Rahim (AMD) <44449863+saadrahim@users.noreply.github.com>
Rename the file to match the RFC0015 entry in the index.
10.2 is too close to its snap date to land the packaging. The bring-current stage now covers 10.2 as well.
- curated metadata stays with the generator until it is public; the co-location PRs commit the generated .F90, its build, and its tests - tests: coverage is uneven during the migration (rocBLAS and hipBLAS are exercised through clients/ for now, rocRAND/hipRAND tests are not installed yet) - state what exists on develop and what the PRs add: ROCmFortran.cmake comes with the HIP binding, rocRAND/hipRAND's -fortran config is include()d by the C config today, hipBLAS has no libhipblas_fortran.so - handles are type(c_ptr) in every generated module - ASan and coverage: the projects build the bindings, TheRock turns them off - rocSOLVER/hipSOLVER/hipBLAS keep gfortran for clients linking a host LAPACK; say what forcing amdflang implies - hipSOLVER: roc::hipsolver_fortran moves to find_package(hipsolver-fortran) - guard placement, client gating, cmake/toolchains/, hipFFTW packages, hipsparse_enums.f90, rocsparse_error, CODEOWNERS in rocm-systems, share/hip in the lib component
… list - build on TheRock#3928 (FORTRAN_OPTIONAL / FORTRAN_REQUIRED, per-subproject CMAKE_Fortran_COMPILER) instead of describing a second mechanism - ASAN/coverage: TheRock will pass BUILD_FORTRAN_BINDINGS=OFF; today it compiles Fortran uninstrumented - TheRock's host LAPACK is OpenBLAS with C_LAPACK=ON, so amdflang is safe for the clients too - hipSOLVER's .so goes away once rocm-libraries#12581 lands - flang is built on Linux only; the gfortran pick is CMake 3.31's - per-project CMake minimums range from 3.13 to 3.25.2 - hipfort_handles never existed; _types exists only for rocRAND and hipFFTW
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
hipfortprovides the Fortranbind(C)interfaces to the HIP runtime and the ROCm mathlibraries. It lives in its own repository, away from the headers it mirrors, and its
interfaces are partially written by hand, so its coverage is only ever as current as the
last manual update: it drifts behind the C API, and it stalls whenever nobody is
maintaining it.
This RFC proposes fixing that structurally rather than by another catch-up pass:
generate the bindings from the headers, and put them next to those headers, so that a
change to a
.hand the change to its.F90can travel in the same pull request.There is no tracking issue yet. Following
docs/rfcs/README.md, the RFC is itself thepublic record and the place to comment; happy to open an issue or a discussion thread
instead if maintainers prefer.
Technical Details
Documentation only. Adds
docs/rfcs/RFC0015-Fortran-Bindings-Split.md(status: draft)and its entry in the RFC index. No build, packaging, or CI behavior changes here.
What the RFC proposes:
rocm-systems, each math library'sbindings to
rocm-librariesnext to that project, each in a dedicatedfortran/directory rather than inside
include/.headers and emits the modules. When a header changes, CI regenerates the affected
module and suggests the diff on the PR, the way an auto-formatter does.
.F90,.mod,lib<lib>_fortran.a, and CMake target in the C library's existing namespace(
roc::rocblas_fortran,hip::hip_fortran), sofind_package(rocblas)yields the Clibrary and its Fortran binding together.
hipfort_prefix and collapses eachlibrary to one module:
use rocblas,use hip.type(c_ptr)surface, F2008 isneeded for the array ergonomics, and F2018 only for the opt-in assumed-rank variants.
available as source through the 10.x series, the packaged track lands in 10.3. A
"Migration and compatibility" section states the two mechanical edits a user makes (the
userename and the link target), and what the transition does to each population ofcurrent users.
Appendices cover why a
.modand its archive cannot be shared across compilers or evenacross versions of one compiler (the constraint that drives the whole packaging design),
how NVIDIA answers the same problem by owning its compiler, the implementation backlog,
and how the generator is tested.
Test Plan
A documentation-only change, so the checks are the repository's own markdown gates:
Test Result
mdformatreformatted the tables and normalizedordered-list numbering; the content is unchanged and the rendering is identical.
lycheelink check passes: the RFC's links and the new index entry resolve.above.
Submission Checklist
JIRA ID: ROCM-25143