Skip to content

feat(hipblas): add the generated Fortran binding in bindings/fortran/hipblas - #12370

Draft
amontoison wants to merge 8 commits into
ROCm:developfrom
amontoison:users/amontoison/hipblas-fortran-bindings
Draft

amontoison wants to merge 8 commits into
ROCm:developfrom
amontoison:users/amontoison/hipblas-fortran-bindings

Conversation

@amontoison

@amontoison amontoison commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

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

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

What lands

  • bindings/fortran/hipblas/hipblas.F90 (163 733 lines, generated with ROCm/rocm-fortran-generator 9c8b3e4 from the hipBLAS headers, marked linguist-generated): one module hipblas with the bind(C) interfaces, the enum constants, the hipblasCheck helper and array overloads for the routines the generator supports.
  • metadata/hipblas.toml: the generator metadata it was generated with.
  • test/: 209 CTest tests, 126 .f03 tests of the C interfaces and 83 .f08 tests of the array overloads (registered as <name>_f2008). They also install: the executables in bin/, and a CTestTestfile.cmake with the same tests and properties in bin/hipblas-fortran/, for ctest --test-dir.
  • The tests are ported from hipFORT's hipBLAS tests.
  • CMakeLists.txt, the hipblas-fortran config template, cmake/ROCmFortranCompiler.cmake (the same in every binding: ROCm's amdflang is preferred over the first compiler on PATH unless CMAKE_Fortran_COMPILER or FC is set), cmake/toolchains/ and the binding's CHANGELOG.md.
  • .github/CODEOWNERS: /bindings/fortran/hipblas/ @ROCm/rocm-fortran-maintainers @ROCm/hipblas-reviewers.
  • .github/repos-config.json: a bindings/fortran entry, so CI detects changes to the binding. Each binding PR appends its entry at the end of the list, so all but the first to merge need a trivial rebase.

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

Options

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

In TheRock

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

Follow-ups

This binding replaces the hand-written library/src/hipblas_module.f90, which stays for now. Deprecating it, then removing it and moving the library's Fortran clients to this binding, come in separate pull requests.

Build and test

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

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

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

Verification

Standalone against ROCm 10.1 with amdflang on one GPU: 209 tests, 209 pass.

JIRA ID: ROCM-31390

@therock-pr-bot

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

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

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

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

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

🙋 Wish to Override Policy?

@therock-pr-bot

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

Copy link
Copy Markdown

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

@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch from 1affc44 to cbe1821 Compare September 24, 2026 16:49
amontoison added a commit to amontoison/rocm-cmake that referenced this pull request Sep 24, 2026
…gets

A library that ships generated Fortran bindings installs them as their own
config package, <package>-fortran-config.cmake, so that the binding can be built
and installed independently of the C library -- which is the supported path for
anyone whose Fortran compiler is not the one ROCm ships the bindings for.

For find_package(<package>) to then expose <ns>::<package>_fortran, the C
package has to pick that file up as a sibling. rocm_export_targets already has
an INCLUDE argument, and it is not usable for this, for two independent reasons:

  - it emits a bare include(), so the file must always exist, whereas a Fortran
    binding is present only when BUILD_FORTRAN_BINDINGS was on and a Fortran
    compiler was available; and
  - it emits it BEFORE the targets file, so the Fortran config would run before
    the imported C targets exist, and the Fortran interface library could not
    link against them.

So emit a separate include, after the targets and marked OPTIONAL. It is a no-op
for every package that ships no such file, which is all of them today, and it
lets a Fortran binding installed after the C library be found at
find_package(<package>) time and ignored when absent.

Guarded against the case where a caller already passed the same file through
INCLUDE, so it is not included twice.

rocm_write_package_template_function joins ARGN with spaces into NAME(...), so
the trailing OPTIONAL keyword passes through verbatim; no new emission path is
needed. Verified, the emitted line is

  include("@PACKAGE_CONFIG_PACKAGE_INSTALL_DIR@/rocblas-fortran-config.cmake" OPTIONAL)

using the same @PACKAGE_...@ substitution the targets include already relies on,
and include(... OPTIONAL) on a missing file is confirmed to be a clean no-op.

Needed by the RFC0014 Fortran bindings rollout in rocm-libraries and
rocm-systems (ROCm/rocm-libraries#12370, #12505, #12506, #12514, #12533).
@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch 3 times, most recently from 02b3d7f to e601d68 Compare September 25, 2026 02:04
@amontoison amontoison changed the title feat(hipblas): add generated Fortran bindings (RFC0014) feat(hipblas): replace the hand-written Fortran binding with a generated one (RFC0014) Sep 25, 2026
@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch from e601d68 to 63ed4d6 Compare September 28, 2026 03:47
@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch 2 times, most recently from 48eea04 to b0dffaa Compare September 28, 2026 19:42
@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #12370   +/-   ##
========================================
  Coverage    75.95%   75.95%           
========================================
  Files         2880     2880           
  Lines       479025   479025           
  Branches     71958    71958           
========================================
  Hits        363828   363828           
  Misses       90338    90338           
  Partials     24859    24859           
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 48.93% <ø> (ø) Carriedforward from 303be95
TensileLite-Unit 83.68% <ø> (ø) Carriedforward from 303be95
hipBLAS 90.62% <ø> (ø)
hipBLASLt 64.43% <ø> (ø) Carriedforward from 303be95
hipCUB 82.68% <ø> (ø) Carriedforward from 303be95
hipDNN 86.78% <ø> (ø) Carriedforward from 303be95
hipFFT 42.00% <ø> (ø) Carriedforward from 303be95
hipRAND 76.12% <ø> (ø) Carriedforward from 303be95
hipSOLVER 69.67% <ø> (ø) Carriedforward from 303be95
hipSPARSE 86.99% <ø> (ø) Carriedforward from 303be95
rocBLAS 68.73% <ø> (ø) Carriedforward from 303be95
rocFFT 48.10% <ø> (ø) Carriedforward from 303be95
rocRAND 57.30% <ø> (ø) Carriedforward from 303be95
rocSOLVER 76.74% <ø> (ø) Carriedforward from 303be95
rocSPARSE 76.92% <ø> (ø) Carriedforward from 303be95
rocThrust 93.15% <ø> (ø) Carriedforward from 303be95

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

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

@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch 2 times, most recently from e491e5b to 08c9e40 Compare October 4, 2026 03:45
@amontoison amontoison changed the title feat(hipblas): replace the hand-written Fortran binding with a generated one (RFC0014) feat(hipblas): replace the hand-written Fortran binding with a generated one Oct 4, 2026
@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch from 08c9e40 to 8a970ae Compare October 5, 2026 05:12
Add fortran/hipblas.F90, the hipblas module generated from
the C headers by the rocm-fortran generator under RFC0019
(ROCm/TheRock#8122). It is committed next to the headers, is not
edited by hand, and .gitattributes marks it linguist-generated.
@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch 2 times, most recently from 23daf28 to 81e7888 Compare October 22, 2026 15:30
…ted one

Build fortran/hipblas.F90 as roc::hipblas_fortran from fortran/, a CMake
project of its own that the root adds. BUILD_FORTRAN_BINDINGS (default
${UNIX}, OFF on the CUDA backend) and FORTRAN_ARRAY_INTERFACES (default
assumed-shape) control it; the existing BUILD_FORTRAN_CLIENTS is forced
OFF when no binding is built. HIPBLAS_BUILD_FORTRAN_* override both per
library. The .mod and the archive install per compiler under
<includedir>/fortran/<compiler> and <libdir>/fortran/<compiler>, beside
a hipblas-fortran config package.

Remove library/src/hipblas_module.f90. Its hipblas_enums module is
folded into hipblas, so use hipblas_enums becomes use hipblas, and
hipblasCreate and the getters take their output by reference. The
clients shims and samples use the generated module; a client-only
hip_datatypes_stub.F90 stands in for the HIP binding until
ROCm/rocm-systems#11923 lands. There is no fortran/test suite.

Refs: ROCm/TheRock#8122 (RFC0019)
@amontoison
amontoison force-pushed the users/amontoison/hipblas-fortran-bindings branch from 81e7888 to 0940a13 Compare October 22, 2026 18:13
The hipBLAS Fortran binding consumes hipBLAS's public API and builds
standalone against an installed hipBLAS, so it moves out of the library
into bindings/fortran/hipblas, the tree every monorepo and TheRock use for
the Fortran bindings (RFC0015). Nothing is wired into the library build
any more: the library is back to its state on develop. Its hand-written
Fortran module stays for now: its deprecation and removal, with the
Fortran clients that use it, follow in separate pull requests.

- bindings/fortran/hipblas reads hipBLAS's version from projects/hipblas
- the binding has its own .gitattributes and CHANGELOG.md
- CODEOWNERS: /bindings/fortran/hipblas/, same owners
- repos-config.json: register bindings/fortran/hipblas so CI detects changes
@github-actions github-actions Bot added github actions project: none Does not target any component labels Nov 3, 2026
@amontoison amontoison changed the title feat(hipblas): replace the hand-written Fortran binding with a generated one feat(hipblas): add the generated Fortran binding in bindings/fortran/hipblas Nov 3, 2026
…tests

- regenerate bindings/fortran/hipblas with rocm-fortran-generator 9c8b3e4
- commit its metadata in bindings/fortran/hipblas/metadata/, where the
  generator reads it from a checkout
- add the binding's tests in test/, under BUILD_FORTRAN_CLIENTS, ported
  from hipFORT's hipBLAS tests: the library's own clients still test the
  hand-written module while it is deprecated, so they did not test the
  binding
- drop hip_datatypes_stub.F90, a stand-in for the HIP module that the
  library's clients used and nothing builds any more
Install the test executables in bin/, and a CTestTestfile.cmake in
bin/hipblas-fortran/ with the same tests and properties as the build tree,
so that ctest --test-dir runs them from an install, as TheRock's test
jobs do for the libraries.
The binding is built against an installed hipBLAS and is never added to the
library's build, so drop what only served that: the per-library
BUILD_FORTRAN_* overrides, the PARENT_SCOPE results, the ROCM_HAVE_FORTRAN
shortcut, the gating on the library's client and test options, and the
comments about the root. Find the Fortran compiler through the
cmake/ROCmFortranCompiler.cmake shared by all the bindings, and require
CMake 3.19.

The binding targets the ROCm backend only, so BUILD_FORTRAN_BINDINGS no longer
defaults to OFF on the CUDA backend.
…-fortran

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

rocm-cmake's generated hipblas-config.cmake is to include
lib/cmake/hipblas-fortran/hipblas-fortran-config.cmake after its
targets (ROCm/rocm-cmake#303). Skip find_dependency(hipblas) when
hipblas is the package being found, not only when roc::hipblas is
already imported, so that include never re-enters hipblas-config.cmake.

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant