Repository navigation
feat(fortran): add generated Fortran bindings for HIP - #11923
amontoison wants to merge 7 commits into
Conversation
✅ All Policy Checks Passed
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🚫 Please fix the failed policies before requesting reviews. The following policy checks failed:
The |
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 ----- 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 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. ROCm ships no 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.
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.
…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.
…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.
…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.
…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.
…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.
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.
…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.
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.
…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.
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.
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 19 tests under CTest. All 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. They are labelled "gpu", 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. With the HIP Fortran binding available, 19 of 19 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.
…rated one hipsolver.F90 is generated from the hipSOLVER 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, `hipsolver`, carrying the interfaces, the enum constants, the opaque handles and the hipsolverCheck status helper. A consumer writes one `use hipsolver` and links roc::hipsolver_fortran. Implements RFC0014 (ROCm/TheRock#8122) for hipSOLVER, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. Removing the hand-written binding --------------------------------- library/src/hipsolver_module.f90 is removed, along with the install(FILES ...) rule that shipped it into include/hipsolver and the backward-compatibility symlinks to it. It was deprecated in hipSOLVER 2.3.0 (ROCm 6.3.0) and was shipped and built by default, so the removal is user visible: the module keeps the name `hipsolver`, but the separate `hipsolver_enums` module is gone -- its constants are part of `hipsolver` -- and consumers get a static archive and a .mod rather than a shared library plus a .f90 to build themselves. No enumerators are lost, which is the thing that bit hipBLAS. hipsolver_enums declared 27 enumerators; all 27 are present in the generated module, which declares 58. Neither module carries HIP's hipDataType enumerators, so hipSOLVER needs nothing like the hip_datatypes_stub.F90 hipBLAS had to add. EXPORT_FORTRAN_BINDINGS is removed with the target it controlled: it only chose whether the old shared hipsolver_fortran joined the hipsolver-targets export set. The generated binding has an export set and a config package of its own. clients no longer compiles its shim against the removed module; it links the target ../fortran exports. Both halves used the target name hipsolver_fortran, which is why the previous revision of fortran/ had to call its target hipsolver_fortran_bindings and paper over it with EXPORT_NAME and OUTPUT_NAME; that workaround is gone with the clash. Two latent bugs in the client shim ---------------------------------- Both were invisible while the shim compiled against a hand-written binding that made the same mistakes, and both are errors against the generated one. hipsolver{SS,DD,CC,ZZ}gels and ...gesv declare lwork as size_t in hipsolver-functions.h AND in the shim's own C++ prototype in hipsolver_fortran.hpp, but the Fortran shim typed it integer(c_int), as did the removed module. Eight functions now say integer(c_size_t). hipsolver{S,D,C,Z}gesvd{,_bufferSize} take jobu and jobv as signed char. The shim keeps integer(c_signed_char) to match the C++ prototype it exposes, and now converts with achar(..., kind=c_char) at the eight call sites, because the generated binding types the C signed char as character(c_char). Linking against an older hipSOLVER ---------------------------------- The archive is built with -ffunction-sections -fdata-sections and exports --gc-sections to its consumers. A static archive links at object granularity, so pulling in one wrapper pulls in every undefined C symbol the object references; a consumer who never touches API their installed libhipsolver lacks would still fail to link. Against the ROCm installed here every symbol the module references is already present, so this is insurance rather than a fix for a present failure, matching the flags the rest of the series carries. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through HIPSOLVER_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. HIPSOLVER_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. The recorded HIPSOLVER_FORTRAN_COMPILER_DIR is only a default: the config prefers the consumer's own compiler when its .mod is installed under the prefix, repoints INTERFACE_INCLUDE_DIRECTORIES and every IMPORTED_LOCATION_<CFG> when that differs from the recorded directory, and otherwise names what IS available. The generated source is installed as share/hipsolver/fortran/hipsolver.F90, so a user on a compiler ROCm ships no .mod for can rebuild the binding without cloning a monorepo. Under share/ and not include/, because everything under include/fortran/ is partitioned by compiler and the config enumerates that directory to report which compilers are present. This uses the SHARED layout: the real config is co-installed in lib/cmake/hipsolver beside the C package, with a forwarder in lib/cmake/hipsolver-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; hipsolver-config.cmake has no such include, checked against an installed ROCm. A config-version file is installed into BOTH package directories, because CMake looks for it next to the *-config.cmake it actually resolved and the versioned spelling resolves the forwarder. Its version is parsed from this tree's VERSION_STRING rather than from hipsolver_VERSION -- that variable is set by the find_package(hipsolver) this directory does for its link interface, so it would report whatever hipSOLVER happens to be installed. Tests ----- 48 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.
rocsolver.F90 is generated from the rocSOLVER 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 module, `rocsolver`, carrying the interfaces, the enum constants, the opaque handles and the rocsolverCheck status helper. A consumer writes one `use rocsolver` and links roc::rocsolver_fortran. Implements RFC0014 (ROCm/TheRock#8122) for rocSOLVER, following the shape already reviewed for HIP in ROCm/rocm-systems#11923. This is an add, not a replacement: rocSOLVER ships no hand-written Fortran module, so nothing is removed and no existing consumer changes. Depends on the rocBLAS binding ------------------------------ Alone in this series, this binding is not self-contained at COMPILE time. rocsolver-functions.h includes rocblas.h and the rocSOLVER API is spelled in rocBLAS types, so the generated module opens with use rocblas, only: rocblas_diagonal_non_unit, rocblas_fill_upper, rocblas_handle_t, rocblas_operation_none, rocblas_side_left, rocblas_status_success and rocblas.mod, built by the SAME compiler, must exist before the archive can be compiled at all. In-tree the rocblas_fortran target is already defined; standalone the directory finds the rocBLAS Fortran package, searching lib/cmake/rocblas for the real config as well as the default suffixes that the forwarder in lib/cmake/rocblas-fortran covers. Absent, the directory says so and returns, leaving the rocSOLVER C library to build normally: BUILD_FORTRAN_BINDINGS is ON by default, so a missing optional binding must not take the whole library down with it. The lookup happens before the target is created, so nothing is left half configured. The dependency is PUBLIC, not INTERFACE, because a consumer that says `use rocsolver` needs rocblas.mod on its own include path: the compiler follows the module's use-association to read it. The config package carries this through, importing roc::rocblas_fortran before the targets file and naming it when it is missing. Linking against an older rocSOLVER ---------------------------------- The archive is built with -ffunction-sections -fdata-sections and exports --gc-sections to its consumers. Against ROCm 10.0 (librocsolver 3.36) 52 of the C symbols this module references are missing, the cholqr, gehd2/gehrd and *_64 families that 3.38 adds. A static archive links at object granularity, so pulling in one wrapper pulls in every undefined C symbol the object references: a program that does nothing but call rocsolverCheck fails with 156 undefined references without these flags, and links with them. Only a consumer that touches a module procedure (rocsolverCheck, or any array overload) pulls the object in at all; one that calls the plain bind(C) interfaces references the C symbols directly. That is why the failure looks arbitrary from the outside, and why the flags are not optional. Build options ------------- BUILD_FORTRAN_BINDINGS (ON, guarded) and BUILD_FORTRAN_TESTS (OFF, guarded), both overridable per library through ROCSOLVER_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. ROCSOLVER_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. The recorded ROCSOLVER_FORTRAN_COMPILER_DIR is only a default: the config prefers the consumer's own compiler when its .mod is installed under the prefix, repoints INTERFACE_INCLUDE_DIRECTORIES and every IMPORTED_LOCATION_<CFG> when that differs from the recorded directory, and otherwise names what IS available. The generated source is installed as share/rocsolver/fortran/rocsolver.F90, so a user on a compiler ROCm ships no .mod for can rebuild the binding without cloning a monorepo. Under share/ and not include/, because everything under include/fortran/ is partitioned by compiler and the config enumerates that directory to report which compilers are present. This uses the SHARED layout: the real config is co-installed in lib/cmake/rocsolver beside the C package, with a forwarder in lib/cmake/rocsolver-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; rocsolver-config.cmake has no such include, checked against an installed ROCm. A config-version file is installed into BOTH package directories, because CMake looks for it next to the *-config.cmake it actually resolved and the versioned spelling resolves the forwarder. Its version is parsed from this tree's VERSION_STRING (3.38.0) rather than from rocsolver_VERSION -- that variable is set by the find_package(rocsolver) this directory does for its link interface, so it would report whatever rocSOLVER happens to be installed (3.36.0 here). Tests ----- 82 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.
| # duplicating the real config, which would also need its own copy of the targets | ||
| # file and would then be a second thing to keep in step. | ||
| file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/forward/hip-fortran-config.cmake" | ||
| "# Generated forwarder. The real config lives beside the HIP C package, in | ||
| # lib/cmake/hip, so that hip-config.cmake can include it as a sibling. This file |
There was a problem hiding this comment.
🤖 AI-assisted pre-review (for @mangupta)
[BLOCKING] Create the forwarder directory before writing the package config
The configuration writes forward/hip-fortran-config.cmake without first creating the forward directory.
Suggested fix: Add file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/forward") before file(WRITE ...), or write the forwarder directly to an existing binary-directory path.
There was a problem hiding this comment.
Not applicable.
file(WRITE) creates missing parent directories itself.
From the CMake docs for file(WRITE) (https://cmake.org/cmake/help/latest/command/file.html#writing):
Any directories in the path specified by <filename> that do not exist will be created.
Verified with the exact construct from this file:
cmake_minimum_required(VERSION 3.16)
project(t NONE)
file(WRITE
"${CMAKE_CURRENT_BINARY_DIR}/forward/hip-fortran-config.cmake"
"hello\n")
$ ls build/forward/
hip-fortran-config.cmake
No MAKE_DIRECTORY, no error.
This behaviour is documented and has been in place for many releases, so it is not a recent addition.
That said, the finding did point at a real gap: nothing in the surrounding comments explained why the forwarder needs a subdirectory at all.
It is there because the real config, configured at line 382, already occupies ${CMAKE_CURRENT_BINARY_DIR}/hip-fortran-config.cmake, the same basename, so the forwarder needs a directory of its own.
I will explain it in the comment block.
|
@mangupta Is it possible to get another review? We need this for 10 PRs in |
|
🤖 AI-assisted pre-review (for @mangupta) Re-reviewed the updated head ( |
|
🤖 AI-assisted pre-review (for @mangupta) Re-reviewed the updated head ( |
Add projects/fortran/hip.F90, the hip module generated from the HIP C headers by rocm-fortran-generator under RFC0015 (ROCm/TheRock#8122). projects/fortran is a standalone project for the Fortran bindings of the rocm-systems libraries. The module is not edited by hand: .gitattributes marks it linguist-generated, and metadata/ holds what the C headers cannot express (scalar arguments, optional arguments, by-value arguments, function pointers), read by the generator when it runs on this checkout.
Build projects/fortran/hip.F90 as hip::hip_fortran, a standalone CMake
project built against an installed HIP (find_package(hip)).
BUILD_FORTRAN_BINDINGS (default ${UNIX}), BUILD_FORTRAN_CLIENTS (default
ON) and FORTRAN_ARRAY_INTERFACES (default assumed-shape) control it, and
HIP_BUILD_FORTRAN_* override them. The .mod and the archive install per
compiler under <includedir>/fortran/<compiler> and
<libdir>/fortran/<compiler>, beside a hip-fortran config package.
shared/cmake/ROCmFortran.cmake adds the amdflang-first compiler probe
for rocm-systems projects.
test/ adds 41 CTest tests labelled gpu (39 without a HIP compiler). The
Fortran tests of the rocm-libraries bindings use hip and skip until this
lands.
Refs: ROCm/TheRock#8122 (RFC0015)
The binding consumes HIP's public API and builds standalone against an installed HIP, so it gets its own top-level tree instead of sitting next to the implementation projects: projects/fortran moves to bindings/fortran, the layout every monorepo and TheRock use for the Fortran bindings. - read HIP's VERSION from projects/hip, now two levels up - CODEOWNERS: /bindings/fortran/, same owners - repos-config.json: register bindings/fortran so CI detects changes to it, as for emulation/rocjitsu
Install the test executables in bin/, and a CTestTestfile.cmake in bin/hip-fortran/, with the same tests and properties as the build tree, so that ctest --test-dir runs them from an install, as TheRock's test jobs do for the libraries. The code object of module_kernel and library_module installs beside it, and they find it by a relative path.
…object TheRock's hipcc comes from the HIP install and does not know where the device libraries are; it passes their path through HIP_FORTRAN_GENCO_FLAGS.
Implements RFC0015, Fortran Bindings Split for HIP: the Fortran binding is generated from the C headers and committed next to them. Shape previewed in ROCm/hipfort#540.
What lands
bindings/fortran/, a standalone project for the Fortran bindings of the rocm-systems libraries. ROCTx follows in feat(fortran): add the ROCTx Fortran binding to bindings/fortran #14024 in the same directory.bindings/fortran/hip.F90(45 281 lines, generated, markedlinguist-generated): one modulehipwith the interfaces, enums, derived types and thehipCheckhelper. Code using hipFORT'shipfortmodule for HIP writesuse hip.bindings/fortran/metadata/hip.toml: what the C headers cannot express (scalar, optional, by-value and function-pointer arguments), one table per C function, read by the generator when it runs on this checkout. Everything else is derived from the C signature.c_loc(x). Outputs the API documents as nullable (sizeOut, the capture id, the graph node and edge arrays,bytesofhipModuleGetGlobal) areoptional; omitting one passes NULL, sohipGraphGetNodescan return only the count. Handles are plaintype(c_ptr). As in hipFORT, every functionXis a generic around itsbind(C)specificX_.find_package(hip)); clr is untouched. The newshared/cmake/ROCmFortran.cmakepublishesROCM_HAVE_FORTRANto rocm-systems projects.bindings/fortran/test/registers 41 runtime tests, labelledgpu; the four that use a kernel need the HIP language (occupancy,cooperative_launch) orhipcc(module_kernel,library_module), and a device lacking a feature reports the test skipped.Options
BUILD_FORTRAN_BINDINGS${UNIX}BUILD_FORTRAN_CLIENTSONtest/FORTRAN_ARRAY_INTERFACESassumed-shapeassumed-shape(per rank, Fortran 2008),assumed-rank(dimension(..), Fortran 2018) ornoneHIP_BUILD_FORTRAN_*BUILD_FORTRAN_*optionsWithout
CMAKE_Fortran_COMPILERorFC, ROCm'samdflangis preferred over the first compiler onPATH.Build and test
From the repository root; the rocm-libraries tests find the binding in
$PREFIX:cmake -S bindings/fortran -B build/fortran \ -DCMAKE_Fortran_COMPILER=/opt/rocm/bin/amdflang \ -DCMAKE_PREFIX_PATH=/opt/rocm -DCMAKE_INSTALL_PREFIX="$PREFIX" cmake --build build/fortran ctest --test-dir build/fortran --output-on-failure cmake --install build/fortranFiles install, in the
devcomponent, underinclude/fortran/<compiler>/andlib/fortran/<compiler>/(GNUInstallDirs); a consumer usesfind_package(hip-fortran)andtarget_link_libraries(app PRIVATE hip::hip_fortran), and setsHIP_FORTRAN_COMPILER_DIRto pick another compiler's build.Verification
hip.F90andmetadata/hip.tomlare byte-identical to the output of ROCm/rocm-fortran-generator9c8b3e4run on this checkout (strict mode), ondevelop7215ce9.Standalone configure, build and test against ROCm 10.2 on one gfx1101 GPU, with amdflang and gfortran 13.3, each under the three
FORTRAN_ARRAY_INTERFACESvalues: all tests pass in the six configurations (41 registered, 34 withnone, which skips the f2008 tests).mem_advise,peer_copyandcooperative_launchreport skipped on this device. Against ROCm 10.1,rdma_flushandlibrary_moduledo not link (their entry points are newer than its HIP); the other tests pass, from the build tree and from an install withctest --test-dir $PREFIX/bin/hip-fortran(/opt/rocm/libonLD_LIBRARY_PATH).JIRA ID: ROCM-31390
The bindings live in
bindings/fortran/, rocm-systems' tree for API consumers, outside the implementation projects (RFC0015): they use only the public API and build standalone against the installed libraries.