Migrating to the Fortran bindings shipped in ROCm#

Who this is for#

You build hipFORT yourself and call ROCm through it: use hipfort_rocblas, hipMalloc, rocblas_dgemm.

In one line: the bindings move into ROCm itself (rocm-systems and rocm-libraries), you rename your use statements and link a per-library Fortran archive, and nothing else in your code changes.

Note

Using a ROCm library’s own Fortran module instead? If you write use rocblas against /opt/rocm/include/rocblas/rocblas_module.f90, or use rocsparse, or use rocrand_m, this page is not yours. Those modules ship with the library rather than with hipFORT, and their migration has a different deadline, different edits, and, unlike this one, call sites that do change. See Migrating from a library’s own Fortran module.

Coming from CUDA Fortran? See Migrating from CUDA Fortran.

Why the bindings are moving#

hipFORT is a separate repository that you build and install next to ROCm. It has always lagged behind ROCm: a routine added to rocBLAS reached Fortran only when hipFORT was regenerated, which for several years did not happen at all, and a hipFORT build had to be matched by hand to the ROCm it ran against. Moving the bindings into ROCm fixes that at the root:

  • Always complete and current. Each binding is generated from the headers of the library it ships with, committed in the bindings/fortran/ tree of the same repository, and kept in sync by CI whenever a header changes. Every entry point the .so exports is declared, and none that it does not.

  • Nothing extra to build. The bindings arrive precompiled with ROCm: in TheRock’s tarballs from the 10.3 tech preview, and in the amdrocm-<family>-fortran-devel packages from 10.4. There is no separate project to clone, configure, and keep in step.

  • Pay for what you use. One module and one archive per library, built against that library in a separate stage and shipped in the family’s Fortran package, instead of one hipFORT build for everything, so a code that only calls rocBLAS needs only rocBLAS’s binding.

  • One way to build and find them. The same CMake options, install layout, and find_package pattern across all thirteen bindings, where today each library that has a Fortran module does it differently.

  • Easier to improve. Because the bindings are generated, a request such as a typed overload, a missing routine, or a corrected argument type becomes a generator change that reaches every library at once, instead of a hand edit that has to be repeated in each.

The price is the migration on this page: two mechanical edits, done once.

Are there breaking changes?#

Yes, but they are limited and mechanical: your code will not compile or link unchanged. Two edits are required, and the CUDA backend is dropped.

  • Source. The module names change: use hipfort_rocblas becomes use rocblas.

  • Build. The link target changes: find_package(hipfort) and hipfort::rocblas become find_package(rocblas-fortran) and roc::rocblas_fortran.

  • NVIDIA users. The CUDA (nvptx) backend is not carried into the new bindings.

Everything at the call level (routine names, arguments, calling styles) is unchanged, so the two edits are find-and-replace, not a rewrite. The details are in What you change.

Timeline#

ROCm

What happens

≤ 10.2

Nothing changes. Keep using hipFORT as today.

10.3

The new bindings ship as a tech preview, in TheRock’s tarballs and, if they are ready, in the OS packages. Their interfaces can still change. hipFORT is still maintained beside them.

10.4 to 10.x

The new bindings are production: they ship in the OS packages, with the full documentation and the compatibility promise below. hipFORT is still maintained, so both work and you can migrate at any point in this window. Aim for the start of it rather than the end.

11.0

hipFORT is removed. You must be on the new bindings by this release.

Do I need to do anything now? No. Today’s hipFORT keeps working until it is removed at ROCm 11.0, and old and new share the same interfaces underneath, so you migrate on your own schedule. Migrate early anyway: the edit is mechanical, but if something does behave differently you want releases to spare, and an early report gets fixed for everyone.

From 10.4, a binding is versioned with its library and stays valid across a major ROCm series in one direction: a binding built for 10.4 still links against the libraries of any later 10.x, and the CMake package accepts any version with the same major number. The 10.3 tech preview carries no such promise. A binding newer than the libraries it links against is another matter (Binding and library versions). You revisit your build at a major release, not at every point release.

Codes that build on several ROCm versions#

If one code base has to build on systems that will not reach ROCm 10.3 for a while (a production machine frozen on ROCm 6.x, for example) and on newer ones, you have two options:

  • Stay on hipFORT until your oldest system reaches 10.3. hipFORT keeps working through the 10.x series, so a single hipFORT-based build covers everything until then. On each system, use the hipFORT release that matches its ROCm (hipFORT tags them rocm-<version>, for example rocm-6.3.3): a binding declares the entry points of the ROCm it was generated from, and a newer one can reference routines an older .so does not export. hipFORT’s develop branch is compiled with one section per procedure, so a program linked with -Wl,--gc-sections also builds against an older ROCm, as long as it calls only routines that ROCm exports.

  • Switch per system with a thin wrapper module. Both bindings export the same names, so a module of your own can pick one at compile time, and the rest of your code uses the wrapper and never sees the difference:

    ! my_rocblas.F90 (capital F: preprocessed)
    module my_rocblas
    #ifdef HAVE_ROCM_FORTRAN
      use rocblas
    #else
      use hipfort_rocblas
      use hipfort_rocblas_enums
    #endif
    end module my_rocblas
    
    find_package(rocblas-fortran CONFIG QUIET)
    if(TARGET roc::rocblas_fortran)
      target_link_libraries(app PRIVATE roc::rocblas roc::rocblas_fortran)
      target_compile_definitions(app PRIVATE HAVE_ROCM_FORTRAN)
    else()
      find_package(hipfort REQUIRED)
      target_link_libraries(app PRIVATE hipfort::rocblas)
    endif()
    

    Test the target rather than rocblas-fortran_FOUND: the package can be found but have nothing installed for your compiler.

If you need the new bindings on a ROCm older than 10.3, open an issue saying which release: the bindings are generated from a release’s headers, and an older release can be generated on request.

Do I need to build anything?#

Usually not. Find your case:

Your situation

What you build

ROCm 10.3 or later, compiling with amdflang

Nothing. The .mod and .a files are installed with ROCm. Point your build at them (Compile and link).

ROCm 10.3 or later, compiling with gfortran, Cray ftn, or any other compiler

Each binding you use, once per compiler. A .mod only works with the compiler that wrote it. The sources are installed with ROCm, so this is one short build per library (Building a binding with your compiler). The C libraries are not rebuilt.

You build ROCm itself from source (Spack, EasyBuild, a distribution package)

One more project per binding. The bindings are not built with the libraries: each is a project of its own, in the bindings/fortran/ tree of the repository that holds its library, built after the library and against it (Building a binding with your compiler). TheRock builds them all.

ROCm older than 10.3

hipFORT, as today. See Codes that build on several ROCm versions.

Windows

Each binding you use, from the repository. ROCm for Windows ships no Fortran compiler, so it ships neither the compiled bindings nor their sources. See Windows.

What you change#

Two things: the modules you use, and the Fortran library you link. Your actual calls (routine names, arguments, calling style) do not change.

Rename your use statements#

The hipfort_ prefix is dropped, and each library collapses to a single module named after the library. hipFFT is the exception, with a second module for its Xt API (see below).

Old use (hipfort_ prefix, split modules)

New use

Link (CMake target)

CMake package

use hipfort (HIP runtime; plus hipfort_types, hipfort_enums)

use hip

hip::hip_fortran

hip-fortran

use hipfort_roctx

use roctx

roc::roctx_fortran

roctx-fortran

use hipfort_rocblas (plus _enums)

use rocblas

roc::rocblas_fortran

rocblas-fortran

use hipfort_hipblas (plus _enums)

use hipblas

roc::hipblas_fortran

hipblas-fortran

use hipfort_rocsparse (plus _enums)

use rocsparse

roc::rocsparse_fortran

rocsparse-fortran

use hipfort_hipsparse (plus _enums)

use hipsparse

roc::hipsparse_fortran

hipsparse-fortran

use hipfort_rocfft (plus _enums)

use rocfft

roc::rocfft_fortran

rocfft-fortran

use hipfort_hipfft (plus _enums, _types)

use hipfft

hip::hipfft_fortran

hipfft-fortran

use hipfort_hipfftxt (plus _enums, _types)

use hipfftxt

hip::hipfft_fortran

hipfft-fortran

use hipfort_hipfftw (plus _enums, _types)

use hipfftw

hip::hipfftw_fortran

hipfftw-fortran (built by hipFFT’s binding project)

use hipfort_rocsolver (plus _enums)

use rocsolver

roc::rocsolver_fortran

rocsolver-fortran

use hipfort_hipsolver (plus _enums)

use hipsolver

roc::hipsolver_fortran

hipsolver-fortran

use hipfort_rocrand (plus _enums, _types)

use rocrand

roc::rocrand_fortran

rocrand-fortran

use hipfort_hiprand (plus _enums)

use hiprand

hip::hiprand_fortran

hiprand-fortran

hipFFT’s binding has two modules in one archive, as CUDA Fortran has cufft and cufftXt. Every hipfftXt* and hipfftMp* routine is in hipfftxt, including hipfftXtSetWorkArea, and every other hipfft* routine is in hipfft. hipfftxt uses and re-exports hipfft, so a file that calls the Xt API writes use hipfftxt alone. hipFORT gets the same split, into hipfort_hipfft and hipfort_hipfftxt; code that calls the Xt API through hipfort_hipfft moves to use hipfftxt.

The HIP memory helpers you might use directly (hipfort_hipmalloc, hipfort_hipmemcpy, hipfort_hiphostregister) fold into use hip as well.

The shared helper modules go away. Delete these use lines; their symbols now come from the library module you already use:

Old

Where the symbols are now

use hipfort_check

In each library module (hipCheck in hip, rocblasCheck in rocblas, and so on)

use hipfort_auxiliary

In hip (hipGetDeviceProperties)

Only hipfort_cuda_errors (the CUDA-backend error enum) has no new equivalent: it is tied to the dropped CUDA backend and retires with hipFORT at 11.0.

A rename looks like this; the calls in between are untouched:

! before
use hipfort
use hipfort_check
use hipfort_rocblas

! after
use hip          ! runtime + hipCheck
use rocblas

This is a replacement, not an addition: delete the old use hipfort_rocblas line.

Warning

Do not keep use hipfort_rocblas and use rocblas in the same scope: both export the same public names (rocblas_dgemm, rocblasCheck, the enums, and so on), so the compiler cannot tell which one you mean and the file will not compile.

Different files in the same program can still migrate independently, because the clash is only within a single scope (see the FAQ).

Doing the rename automatically#

The rename is regular enough to script, so you do not have to walk a large codebase by hand. On a Git tree, this rewrites every use line in place:

libs='roctx|rocblas|hipblas|rocsparse|hipsparse|hipfftw|hipfftxt|rocfft|hipfft|rocsolver|hipsolver|rocrand|hiprand'

sed -i -E \
  -e "/^[[:space:]]*use[[:space:]]+hipfort_($libs)_(enums|types)\b/Id" \
  -e "/^[[:space:]]*use[[:space:]]+hipfort_(check|auxiliary|types|enums)\b/Id" \
  -e "s/^([[:space:]]*use[[:space:]]+)hipfort_($libs)\b/\1\2/I" \
  -e "s/^([[:space:]]*use[[:space:]]+)hipfort_(hipmalloc|hipmemcpy|hiphostregister)\b/\1hip/I" \
  -e "s/^([[:space:]]*use[[:space:]]+)hipfort\b/\1hip/I" \
  $(git ls-files '*.f90' '*.F90')

The first two rules delete the modules that fold away, and the last three rename what is left.

The recipe needs GNU sed: \b and the I flag are GNU extensions, and BSD sed -i takes a suffix argument. On macOS, install GNU sed (brew install gnu-sed) and run the same command with gsed.

The rules cannot step on each other, because _ is a word character: hipfort_rocblas_enums is deleted by rule 1 rather than renamed to rocblas_enums by rule 3. The I flag covers USE HIPFORT_ROCBLAS as well, and only: clauses survive the rename (use hipfort_rocblas, only: rocblas_dgemm becomes use rocblas, only: rocblas_dgemm).

Then read the diff, because a few things are deliberately left to you:

  • A file might end up with two use hip lines (from use hipfort and use hipfort_hipmalloc, for example). That is valid Fortran and compiles fine; collapse them if you prefer.

  • A file that used hipfort_check, hipfort_auxiliary, hipfort_types or hipfort_enums without ever using hipfort itself loses those symbols, because the delete rules take the whole line. Add use hip there.

  • use hipfort_cuda_errors is left untouched on purpose; it has no new equivalent (see above).

  • A file that calls hipFFT’s Xt API through use hipfort_hipfft becomes use hipfft, which does not have it. Change that line to use hipfftxt.

  • Fixed-form sources, continuation lines, and use lines behind preprocessor guards are not covered. grep -rniE 'use[[:space:]]+hipfort' . finds whatever the rules missed.

The recipe above is the whole of what a migration tool would do. If you would rather have the tool, open an issue.

Compiler support#

Which compiler?#

The supported compilers are amdflang (ROCm’s bundled LLVM Flang, the recommended default), gfortran, and Cray Fortran (ftn). Each binding’s project also carries toolchain files for Intel ifx and ifort and NVIDIA nvfortran as a convenience, but those compilers are not in the supported list. Any compiler with Fortran 2003 iso_c_binding should work for the raw type(c_ptr) forms; the default array overloads need Fortran 2008.

One catch is worth knowing: there is no portable Fortran ABI, so a .mod (and its compiled .a) is tied to one compiler, and even one compiler version; two compilers cannot share a .mod. ROCm therefore ships the bindings precompiled for amdflang only, and with any other compiler you build the bindings you use (see Do I need to build anything?).

Note

Mixing amdflang versions. A .mod is tied to the compiler version too. From ROCm 10.1, the opt-in -fmodule-mismatch-check=warn lets amdflang read a .mod written by another amdflang version, warning instead of erroring. It covers version skew inside amdflang only: nothing lets gfortran read an amdflang .mod. Rebuild when you can, because the warning means the two artifacts were not built together.

The C libraries you link (libamdhip64.so, librocblas.so, and so on) are the stable, compiler-agnostic ABI; only the thin Fortran layer is compiler-specific.

Windows#

The bindings are Linux-first. ROCm for Windows ships no Fortran compiler, so BUILD_FORTRAN_BINDINGS defaults to OFF there, and a Windows install contains no .mod, no lib<lib>_fortran archive, and no installed .F90. Nothing in the bindings is Linux-specific, though: they are plain iso_c_binding code. With a Fortran compiler of your own (Intel ifx, for example), take the binding’s directory (bindings/fortran/<library> in rocm-libraries, bindings/fortran in rocm-systems for HIP and ROCTx) from the repository at the tag of your ROCm and build it as in Building a binding with your compiler. This path is not tested yet; if you try it, please report how it went.

Where the files install#

Because the artifacts are compiler-specific, they install under a per-compiler subdirectory: the .mod files in <includedir>/fortran/<compiler>/ and the .a files in <libdir>/fortran/<compiler>/. Several compilers can therefore share one prefix, and a CMake find_package picks your compiler’s subdirectory automatically; if you link with raw flags, point -I and -L at it.

<libdir> and <includedir> are the platform’s own: lib64 on Fedora, RHEL and SUSE, lib/<triplet> on Debian multiarch. A stock ROCm install gives /opt/rocm/include/fortran/amdflang/ and /opt/rocm/lib/fortran/amdflang/. Elsewhere, check the packager’s CMAKE_INSTALL_LIBDIR before writing a path by hand.

<compiler> is the name you would type, not the CMake compiler ID:

Compiler

<compiler>

ROCm’s LLVM Flang

amdflang

GNU

gfortran

Cray

ftn

Intel LLVM / Intel Classic

ifx / ifort

NVIDIA HPC

nvfortran

Anything else falls back to the basename of CMAKE_Fortran_COMPILER, lowercased. The name ignores the compiler version, so two versions of one compiler would share a directory; <LIB>_FORTRAN_COMPILER_DIR (for example -DROCBLAS_FORTRAN_COMPILER_DIR=gfortran-13) gives a build its own, and the CMake package finds it.

If nothing is installed for your compiler, the package fails and names what is, so that you can tell a rebuild from a redirect:

This project builds with gfortran, but no rocrand.mod for it is installed
under /opt/rocm/include/fortran. Available: amdflang. A Fortran .mod cannot
be shared across compilers; rebuild the bindings with gfortran, or set
ROCRAND_FORTRAN_COMPILER_DIR to the directory to use.

The installed sources#

Every binding installs, beside the compiled module, the Fortran source it was compiled from:

<datadir>/<library>/fortran/<library>.F90

which on a stock install is, for example, /opt/rocm/share/rocblas/fortran/rocblas.F90:

Binding

Installed source

HIP

share/hip/fortran/hip.F90

ROCTx

share/roctx/fortran/roctx.F90

hipFFT

share/hipfft/fortran/hipfft.F90, hipfftxt.F90 and hipfftw.F90

Every other library

share/<library>/fortran/<library>.F90 (rocblas, hipblas, rocsparse, hipsparse, rocfft, rocsolver, hipsolver, rocrand, hiprand)

The source is there for three reasons:

  • Any compiler can use ROCm. The .mod and .a only serve amdflang; the .F90 serves every compiler. Nothing to clone, no other repository to track.

  • It cannot disagree with your libraries. It was generated from the same headers as the installed .so and ships in the same release, so it declares exactly the entry points your ROCm exports. A copy taken from a later release or a branch can declare routines your .so does not have, and then fails at link time (Binding and library versions).

  • It is the reference. It is the authoritative list of what the binding declares, with the argument types, readable without a .mod viewer. It carries no documentation comments: the C headers’ documentation applies.

It sits under share/ rather than include/ because it is compiler-independent: everything under <includedir>/fortran/ is partitioned by compiler, so a source file there would be read as naming one.

Building a binding with your compiler#

The .F90 is self-contained Fortran: compiling it needs only a Fortran compiler, no C headers and no .so, since the vendor symbols resolve when you link your application. The C libraries are not rebuilt.

By hand, compile each source you need into a .mod and an object file. The array overloads are behind -DUSE_ASSUMED_SHAPE=1 (or -DUSE_ASSUMED_RANK=1 for the assumed-rank variants); without either you get no array overloads, only the raw type(c_ptr) forms and the forms with optional arguments:

mkdir -p mods
for lib in hip rocblas; do
  gfortran -c -DUSE_ASSUMED_SHAPE=1 -Jmods \
    /opt/rocm/share/$lib/fortran/$lib.F90 -o mods/$lib.o
done

gfortran app.f90 -Imods mods/rocblas.o mods/hip.o \
  -L/opt/rocm/lib -lrocblas -lamdhip64 -o app

To keep only the wrappers you call, add -ffunction-sections -fdata-sections to the first command and -Wl,--gc-sections to the second (Binding and library versions).

With CMake, which also installs the result in the per-compiler layout with its CMake package, so that find_package(rocblas-fortran) works as for the shipped bindings. Each binding’s directory is a self-contained project; build it against your installed ROCm, into a prefix of your own:

cmake -S <rocm-libraries>/bindings/fortran/rocblas -B build/rocblas-fortran \
  -DCMAKE_Fortran_COMPILER=gfortran \
  -DCMAKE_PREFIX_PATH=/opt/rocm \
  -DCMAKE_INSTALL_PREFIX=$HOME/rocm-fortran
cmake --build build/rocblas-fortran
cmake --install build/rocblas-fortran

The project compiles one section per procedure with the compilers that accept the flags, for a program linked with -Wl,--gc-sections (Binding and library versions).

The bindings live in their own bindings/fortran/ tree, apart from the libraries: in rocm-libraries under bindings/fortran/<library> for the math libraries, and in rocm-systems under bindings/fortran for HIP and ROCTx, which one project builds together (cmake -S <rocm-systems>/bindings/fortran -B build/fortran with the same options). Check out the tag of the ROCm you have installed (both repositories tag releases as therock-<version>), for the reason given above.

Then compile your application with -I$HOME/rocm-fortran/include/fortran/gfortran and -L$HOME/rocm-fortran/lib/fortran/gfortran, or add $HOME/rocm-fortran to CMAKE_PREFIX_PATH.

A binding that uses another needs the other’s .mod, built with the same compiler, so build in dependency order. Today that is one case: rocSOLVER uses rocBLAS, so build rocBLAS’s binding first, and put its prefix on CMAKE_PREFIX_PATH (or the -I line) when you build rocSOLVER’s.

Build options#

Skip this section if you only use ROCm’s precompiled bindings. These options control how the bindings are built. They matter if you build ROCm from source, or build a binding yourself as above. They replace the HIPFORT_* options you passed to hipFORT’s build, which you no longer run.

Each binding is a standalone CMake project, in the bindings/fortran/ tree of rocm-systems or rocm-libraries, built against the installed library. No library build adds it. The options below are those of these projects.

BUILD_FORTRAN_BINDINGS replaces “do I build hipFORT at all”. Each binding project exposes it, ON by default on Linux (OFF on Windows, where ROCm ships no Fortran compiler) but guarded: built when a Fortran compiler is present, skipped with a STATUS message when one is not. -DBUILD_FORTRAN_BINDINGS=OFF opts out.

Old hipFORT option

New equivalent

(build hipFORT, or do not)

BUILD_FORTRAN_BINDINGS, ON on Linux but guarded

HIPFORT_USE_FPOINTER_INTERFACES (ON with F2008) and HIPFORT_ASSUMED_RANK (OFF)

Both fold into one tri-state FORTRAN_ARRAY_INTERFACES, which is none, assumed-shape (the default), or assumed-rank (ROCTx has no array overloads and ignores it)

HIPFORT_MULTITOOLCHAIN_LAYOUT (ON)

Gone. The per-compiler layout is unconditional (see Where the files install)

HIPFORT_BUILD_NVPTX (ON)

Gone, with the CUDA backend

HIPFORT_COMPILER, HIPFORT_AR, HIPFORT_RANLIB, HIPFORT_COMPILER_FLAGS, HIPFORT_BUILD_TYPE, HIPFORT_INSTALL_DIR (already deprecated)

Gone. Use the plain CMAKE_* variables, as hipFORT already tells you to

BUILD_TESTING, HIPFORT_ROCM_LIB_DIR, HIPFORT_CUDA_LIB_DIR

BUILD_FORTRAN_CLIENTS (ON). hipFORT’s single suite splits into each binding’s test/ (rocBLAS’s and hipBLAS’s are still to come)

HIPFORT_EXTENDED_TESTS

Gone, with both link-time audits it gated, which checked the bindings themselves rather than your code. What you build is the runtime suite, under BUILD_FORTRAN_CLIENTS

<LIB>_FORTRAN_COMPILER_DIR (for example ROCBLAS_FORTRAN_COMPILER_DIR) overrides the per-compiler subdirectory name (Where the files install).

The array tiers themselves are unchanged: raw type(c_ptr) (Fortran 2003) always present, array overloads (2008) on, assumed-rank (2018) opt-in. One option now selects between them instead of two, because assumed-rank replaces the per-rank variants rather than adding to them: an assumed-rank dummy is not distinguishable by rank from the per-rank specifics, so the two cannot legally coexist in one generic, and two booleans could express that illegal combination. See Fortran interface variants for the call sites side by side. The shipped bindings use the default, assumed-shape, which is what hipFORT gives you today.

Each binding project has its own BUILD_FORTRAN_CLIENTS, ON by default, which builds its test/. Asking for it when the binding was not built is a skip, not an error. The library option of the same name, in rocBLAS, hipBLAS and rocSPARSE, is unrelated: it still builds the Fortran part of the library’s clients/.

To test from CMake whether a binding is available, use if(TARGET roc::rocblas_fortran) after find_package(rocblas-fortran).

Trying the bindings before ROCm 10.3#

The bindings are under review in one pull request per library. Until they ship in a ROCm release, you can try them by building a binding from its pull request branch against a recent ROCm, such as a TheRock nightly, with the commands in Building a binding with your compiler. A branch can be newer than your nightly: link with -Wl,--gc-sections (Binding and library versions), so that a routine the nightly does not have yet fails only if you call it. Build HIP’s binding first: the other bindings’ tests use hip. ROCTx’s binding is built with HIP’s, in rocm-systems’ bindings/fortran/.

Once they are merged, TheRock builds them in a separate stage after the libraries and packages each family’s bindings in one amdrocm-<family>-fortran-devel package. Its nightly builds are the first place to get them precompiled. Reports from trying a real code are especially welcome at this stage: open an issue.

What does not change#

  • Your calls. hipMalloc, rocblas_dgemm, hipblasDgemm, the enum and type names, and hipCheck keep their names and signatures. Only the module you use changes. The bindings come from the same generator as current hipFORT; if you are on an older hipFORT release, a few argument types have since been corrected (an output scalar typed by reference instead of type(c_ptr), for example), and the compiler points at each one.

  • Calling styles. Raw type(c_ptr) still works (including for OpenMP target data), handles are still type(c_ptr), and const char* results are still returned as type(c_ptr). Every routine X is still a generic around a bind(C) specific X_, so the array overloads resolve under the same name and X_ stays callable. Arguments that C accepts as NULL can be omitted (they are optional). ROCTx also accepts a character(kind=c_char) string; append c_null_char yourself ('zone'//c_null_char).

  • The vendor libraries. You still link the same .so (libamdhip64.so, librocblas.so, and so on). Only the Fortran .a and .mod change.

Special cases#

The in-tree Fortran modules that rocBLAS, hipSPARSE, hipRAND and the others shipped themselves have collisions of their own at 10.3; those are covered in Migrating from a library’s own Fortran module, not here.

If you build for NVIDIA (CUDA), the nvptx backend is dropped from the new bindings. It survives only in old hipFORT until 11.0.

If you port code from CUDA Fortran, the hip* modules follow the names of NVIDIA’s CUDA Fortran modules; see Migrating from CUDA Fortran.

FAQ#

Will I be warned before old hipFORT is removed?

Yes. Configuring hipFORT prints a CMake deprecation warning that points to this guide; -Wno-deprecated silences it. A warning when your project calls find_package(hipfort) is planned for the last release before 11.0. Old hipFORT keeps compiling and working through the 10.x series, and nothing is removed before ROCm 11.0, so a build that works today keeps working until then.

Can I install both the old and new bindings at once?

Yes. Nothing collides, so you can migrate one file at a time:

Axis

Old hipFORT

New bindings

Clash?

Module names

hipfort, hipfort_rocblas, …

hip, rocblas, …

No (prefixed versus bare)

.mod files

<includedir>/fortran/<compiler>/hipfort/<backend>/

<includedir>/fortran/<compiler>/

No (different subpaths)

Archives

libhipfort-amdgcn.a

librocblas_fortran.a, …

No (different filenames)

Symbols in the .a

Mangled __hipfort_rocblas_MOD_...

Mangled __rocblas_MOD_...

No (mangled per module name)

CMake package

find_package(hipfort) gives hipfort::rocblas

find_package(rocblas-fortran) gives roc::rocblas_fortran

No

Two rules: build both with the same compiler as your application, and never use both bindings for the same library in one scope. The clash is source-level only. The archives coexist fine, because symbols are mangled per module name, which is why migrating one file at a time works.

Note

This answer is about hipFORT, and the first row of the table is why it cannot extend to a library’s own in-tree module: that one is already named rocblas, not hipfort_rocblas, so there is no prefixed-versus-bare distinction to keep the two apart. Same module name, no coexistence, no file-by-file window. See Migrating from a library’s own Fortran module.

My code is old fixed-form Fortran. Can I use these bindings?

Yes. Fixed form is not an old standard: a .f file with DO ... CONTINUE, implicit typing and a 72-column layout can use hip like any other source. The requirement is on the compiler, which must handle Fortran 2003’s iso_c_binding, not on how your code looks.

The exception is a compiler limited to Fortran 77, which has no modules and so no use statement to write. hipFORT never had a path for that either. If you are stuck there, open an issue rather than hand-writing glue: a C shim with Fortran 77 linkage could be generated from the same headers.

Will my calls break?

Your calls will not: routine names, arguments, and calling styles stay the same. But your code will not compile or link until you make the two edits (rename the use line, change the link target); that is the breaking part, and it is the whole of the migration.

Where do I get the new bindings?

They ship precompiled for amdflang with ROCm: in TheRock’s tarballs from the 10.3 tech preview (and in the OS packages if they are ready), and in the OS packages from 10.4, where you install amdrocm-<family>-fortran-devel (for example amdrocm-blas-fortran-devel), or amdrocm-fortran for all of them. For another compiler, see Building a binding with your compiler; before 10.3, see Trying the bindings before ROCm 10.3.